专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java修炼终极指南:22. 简要介绍Java中的(无)符号整数

temp10 2024-10-29 16:36:22 java教程 15 ℃ 0 评论


有符号值(或变量),如有符号整数或有符号长整数,允许我们表示负数和正数。无符号值(或变量),如无符号整数或无符号长整数,只允许我们表示正数。相同类型的有符号和无符号值(变量)共享相同的范围。但是,如你在下面的图中看到的,无符号变量可以表示更大范围的数值。

Java修炼终极指南:22. 简要介绍Java中的(无)符号整数


图1.20 - 有符号和无符号整数

有符号的32位整数范围从-2,147,483,648到2,147,483,647(大约40亿个值)。无符号的32位整数范围从0到4,294,967,295(也是大约40亿个值)。因此,当我们使用有符号整数变量时,我们可以使用20亿个正数值,但当我们使用无符号整数变量时,我们可以使用40亿个正数值。图中阴影部分表示额外的20亿个正整数值。

通常,当我们根本不需要负值(例如,计算类似事件发生的次数)并且需要使用图1.20中阴影区域中的值时,就需要无符号值。Java仅支持有符号整数,这些整数在有符号系统中使用流行的补码表示法(关于补码表示法和位操作的详细解释,请参阅《Java中的完整编码面试指南》第9章,位操作)。但是,从JDK 8开始,我们还有了无符号整数API,它为无符号算术提供支持。实际上,我们谈论的是在Integer和Long类中添加的一系列静态方法。它们在《Java编码问题》(第一版)的第27(基数中的无符号数字符串)、28(通过无符号转换转换为数字)、29(比较两个无符号值)和30(无符号值的除法和取模)问题中都有涉及。

此外,JDK 9提供了一个名为Math.multiplyHigh(long x, long y)的方法。该方法返回一个long类型,表示两个64位因数的128位乘积的最高有效64位。下面的图阐明了这一说法:


图1.21 - 两个64位因数的128位乘积的最高有效64位

例如:

long x = 234253490223L;  
long y = -565951223449L;  
long resultSigned = Math.multiplyHigh(x, y); // -7187


返回的结果(-7187)是一个有符号值。该方法的无符号版本,unsignedMultiplyHigh(long x, long y),在JDK 18中被引入,其工作原理如下:

// 234253483036  
long resultUnsigned = Math.unsignedMultiplyHigh(x, y);


因此,unsignedMultiplyHigh(long x, long y)返回一个long类型,表示两个无符号64位因数的无符号128位乘积的最高有效64位。但是,请记住,Java支持无符号算术,而不是无符号值/变量。然而,多亏了Data Geekery公司(以著名的jOOQ而闻名),我们有了jOOU(Java面向对象无符号)项目,旨在在Java中引入无符号数字类型。虽然你可以在https://github.com/jOOQ/jOOU上探索这个项目,但下面是一个定义无符号long的示例:

// 使用jOOU  
ULong ux = ulong(234253490223L);  // 234253490223  
ULong uy = ulong(-565951223449L); // 18446743507758328167


并在unsignedMultiplyHigh(long x, long y)中使用它:

long uResultUnsigned = Math.unsignedMultiplyHigh(  
    ux.longValue(), uy.longValue());


你可以在捆绑的代码中找到这些示例。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表