当前位置: 首页 > 知识库问答 >
问题:

Java8无符号整数加法和潜在溢出

丌官承
2023-03-14

我正在练习Cay S.Horstmann的《Java SE 8 for the Really Impatient》一书中的练习。其中一个基于Number类中的改进的练习要求:

编写一个程序,使用< code>int值和无符号运算,对0和232 - 1之间的数进行加、减、除和比较。说明为什么需要< code>divideUnsigned和< code>remainderUnsigned。

问题是,如果您添加2个无符号整数,总和可能会溢出整数限制。我看不出有什么方法可以防止这种情况发生,而不使用long来存储总和并检查它是否大于Integer.MAX_VALUE。只使用整数可以做到这一点吗?

共有2个答案

越嘉树
2023-03-14

为了获得无符号int,需要使用<code>Integer。parseUnsignedInt()函数或执行手动计算。记住,Java实际上并没有无符号整数,Java8只是提供了将int视为无符号整数的能力,以便允许更大范围的正数值。

根据整数类的Java 8文档,

无符号整数将通常与负数关联的值映射到大于 MAX_VALUE

因此,无符号整数和有符号整数之间的转换是,如果数字大于或等于零并且小于或等于 Integer.MAX_VALUE,则它保持不变。如果它大于 Integer.MAX_VALUE 但仍在无符号范围内,则要将其存储在 int 中,则需要向其添加 2^31,由于加法溢出被定义为操作的方式,这会将其转换为正确的值。除了像 int 这样的二进制基元之外,溢出和下溢只会导致计数器重置并继续计数。

int min = Integer.MIN_VALUE;            // -2147483648
int max = Integer.MAX_VALUE;            // 2147483647
int overByOne = Integer.MAX_VALUE + 1;  // -2147483648 : same as Integer.MIN_VALUE
int underByOne = Integer.MIN_VALUE - 1; // 2147483647 : same as Integer.MAX_VALUE

他们的练习只是要求您查看Integer类并测试用于无符号操作的各种(Java8中的新方法)方法。Java没有无符号整数原语,但对于integer类中的某些新方法,int值可以被视为无符号。

宓跃
2023-03-14

用于整数值的 Two 补码具有整洁的属性,无论将值解释为有符号还是无符号,对于加法和减法都无关紧要。

因此,即使在CPU级别,也没有用于加/减有符号或无符号数的独特指令。都是诠释的问题。

因此,当您使用有符号 int 类型添加或减去两个无符号数字时,结果可能会在已签名的 int 范围内溢出。但是,当使用 Integer.toUnsignedString 打印现在的负数时,结果将是正确的无符号值,假设该操作甚至没有溢出无符号整数值范围。

这就是为什么< code>java.lang.Integer类只在必要时才提供特殊的无符号运算,例如比较两个无符号值、除法和余数以及从< code>String到< code>long的转换,而从< code>long到< code>int的类型转换对于其他方向已经足够了。

 类似资料:
  • 我正在读一篇关于整数安全性的文章。以下是链接:http://ptgmedia.pearsoncmg.com/images/0321335724/samplechapter/seacord_ch05.pdf 在第166页,有这样一句话: 涉及无符号操作数的计算永远不会过流,因为不能由结果无符号整数类型表示的结果将被模化为比结果类型可以表示的最大值大一的数字。 这是什么意思?感谢您的回复。

  • 我正在简单的C程序中试验无符号int数据类型和主方法参数。作为一个实验,我写了一个程序,从命令行获取一个int数作为main方法的参数,并对该数和0之间的每个整数求和。 例如,程序计算 f(n) = (1 2 3... n) 当 n 时有效 我开始注意到的第一件事是当f(n) 我手动发现数学上的最大值,我的程序生成的结果将是有效的(例如,在整数溢出之前),对于有符号整数为65535,对于无符号in

  • 问题内容: 我在C ++编写一个程序来找到所有的解决方案一b = c ^,其中一个,b和c ^一起使用所有的数字0-9只出现一次。该程序循环了a和b的值,并且每次在a,b和a b上运行一个数字计数例程,以检查是否满足数字条件。 但是,当a b超出整数限制时,可能会生成伪解。我最终使用如下代码检查了这一点: 有没有更好的测试溢出方式?我知道有些芯片具有发生溢出时设置的内部标志,但我从未见过通过C或C

  • 在Oracle“原始数据类型”页面中,它提到Java8增加了对无符号int和long的支持: 那么,有没有办法声明一个无符号的int或long呢?

  • 未定义行为的一个例子是在flow上的整数行为 有没有一个历史的或者(甚至更好!)造成这种差异的技术原因是什么?

  • 存在一个“3个长整数的平均值”问题,该问题特别涉及三个有符号整数的平均值的有效计算。 然而,使用无符号整数允许进行不适用于前一个问题中所述场景的额外优化。这个问题是关于三个无符号整数的平均值的有效计算,其中平均值向零舍入,也就是说,用我想要计算的数学术语⌊ (a b c)/3⌋. 计算该平均值的简单方法是 首先,现代优化编译器将除法转换为带倒数加移位的乘法,模运算转换为反乘法和减法,其中反乘法可以