Java 发生整数溢出时无符号整数和有符号整数的行为差异
在维基百科上阅读这篇关于 我不太明白为什么有符号整数的溢出会导致未定义的行为,而无符号整数的溢出会导致环绕。为什么它们的行为有区别 另一个问题:编程语言通常有防止整数溢出的保护措施吗Java 发生整数溢出时无符号整数和有符号整数的行为差异,java,c++,c,programming-languages,Java,C++,C,Programming Languages,在维基百科上阅读这篇关于 我不太明白为什么有符号整数的溢出会导致未定义的行为,而无符号整数的溢出会导致环绕。为什么它们的行为有区别 另一个问题:编程语言通常有防止整数溢出的保护措施吗 因为这就是语言的定义方式。它允许在更多种类的硬件上更容易地开发一致性实现(例如,具有饱和算法的DSP) 取决于语言。有些硬件确实如此,您可以在程序中利用这一点 在Java中,只有unsignedint和long值,它们的行为在运行它的任何地方都是一致的。如果在Integer.MAX\u值中加1,则下注Integer
在Java中,只有unsigned
int
和long
值,它们的行为在运行它的任何地方都是一致的。如果在Integer.MAX\u值中加1,则下注Integer.MIN\u值(它会换行),如果从Long.MIN\u值中减去1,则得到Long.MAX\u值
因此,我不知道为什么无符号值的行为在其他语言中是未定义的。C/C++的整数溢出方法是在您正在使用的机器上提供最快的行为,因此在某些机器上(这里假设16位有符号整数): 32766+2==-32768 但在某些机器上: 32766+2==32767 对于其他机器,您可以设置陷阱值或CPU将执行的任何操作 注:Java完美定义了整数溢出,以实现“一次写入,到处运行” 至于无符号整数——它们的大多数应用程序是位掩码、位字段和数字操作(模运算、标识符)——正是您不希望它们未定义的操作 有些编程语言有这样的安全措施,有些没有:
- Python3自动将溢出的值转换为long类型(任意大的整数)
- 在C/C++中,您必须自己检查溢出条件,climits(C)和limits(C++)头为每种类型定义了最大值和最小值
- 在x86汇编程序中编程-无符号有CF(进位标志),有符号有OF(溢出标志)和EFLAGS寄存器,以检查何时发生溢出
许多语言也有任意精度类型,以防您想要避免溢出,但操作速度较慢,因为这样的变量(理论上)可以与你的记忆一样大。 < P>主要的区别在于C和C++语言规范允许使用以下三种不同的符号整数表示< /P>
这将严重降低使用非受欢迎符号表示的平台上的有符号整数算术运算的性能,当然,在C语言和C++语言中,当它涉及到整数运算等基本操作时,它被设计成尽可能接近底层硬件。 行为未定义的原因(与“未指定”相反)这是因为有一些平台故意在整数运算期间出现有符号溢出时生成硬件异常。请注意,该行为仅在算术运算中未定义,而算术运算通常由计算机执行。对于值转换,有符号溢出不会产生未定义的行为(行为实际上是实现定义的)
对于无符号类型,它们在所有平台上的表示都是相同的,这意味着要求所有平台的行为一致不是问题"行为是几乎所有已知二进制硬件平台上的自然行为。在C++中,无符号整数从不溢出。.r.MaTiHHOFFNANDEANES:“你是什么意思?”NPE技术术语,无符号整数的外接结果的包缠行为在技术上是不溢出的。C++中的无符号整数的操作遵循算术规则。ic模2^n,其中n是类型中的位数。这意味着不存在溢出。这可能也有影响。C允许2的补码、1的补码以及符号和幅度,因此不可能像2对无符号整数的补码解释那样指定溢出环绕,因为
-2^(宽度-1)
不能用1的补码和正负号表示。Java int和long都是有符号整数类型,需要表现为2的补码。Java中唯一的无符号整数类型是16位的char。