java带符号整数_关于java:发生整数溢出时无符号和有符号整数的行为差异

在Wikipedia上阅读有关Integer Overflow的文章

我不太了解为什么有符号整数的溢出会导致未定义的行为,而无符号整数的溢出会导致回绕。为什么它们的行为有所不同?

另一个问题:编程语言总体上是否可以防止整数溢出?

在C ++中,无符号整数永远不会溢出。

@ R.MartinhoFernandes:你是什么意思?

@NPE技术术语,超出范围的结果的无符号整数的包装行为在技术上不会溢出。

在C ++中,对无符号整数进行的运算应遵循2 ^ n取模的算术规则,其中n是类型中的位数。这意味着没有溢出。

请注意,在Java中,为所有整数类型指定了环绕行为。

我想知道它与二进制代码中负数的表达方式有关吗?

这可能也有贡献。 C允许二进制补码,一个补码和正负号,因此指定溢出来像无符号整数的二进制补码解释那样来回绕是不可能的,因为-2^(WIDTH-1)不能用一个补码和正负号表示。

C ++ 11 3.9.1-p4:"声明为无符号的无符号整数应服从2 ^ n模的算术定律,其中n是该特定整数大小的值表示形式中的位数。"如果您想知道@ R.MartinhoFernandes标准的哪一部分。

恩,谁的罗伯特?

@ R.MartinhoFernandester非常抱歉(顺便说一句,您的头像帽子使从您的个人资料中复制/粘贴您的名字成为骗局= P)

@WhozCraig? @,R,制表符完整。无需复制。

@WhozCraig:这是不幸的措辞,因为32位算术模n中的1/3为2863311531,但是C ++返回0。(通过评估2863311531u*3u很容易看出。使用32位,结果为1。)如果标准将其限制为加,减和乘,则效果会更好。

Java不支持无符号整数。

整数重复和未定义行为的可能重复

区别的主要依据是以下事实:C和C ++语言规范允许实现使用以下三种不同的带符号整数表示之一

1的补码

2的补码

签名幅度

如果语言规范在有符号溢出的情况下要求某种特定的行为(即,相对于其他两种表示形式偏爱上述表示形式之一),它将迫使基于两个非偏爱表示形式的平台实现"大量"带符号整数运算。由于这种平台的自然机器级别的行为与语言标准所要求的行为不匹配,因此这将是必要的。这些实现必须不断观察有符号的溢出并调整结果以符合标准要求。

这将严重降低使用无偏符号表示的平台上有符号整数算术的性能,这当然在C和C ++这样的语言中是完全不可接受的,C和C ++在设计时尽可能与底层硬件保持紧密联系。它涉及整数运算等基本运算。

行为未定义(而不是* unspecified")的原因是,那里有平台故意在整数算术期间发生有符号溢出的情况下故意生成硬件异常。注意,该行为仅对于算术运算是不确定的对于值转换,有符号溢出不会产生未定义的行为(该行为实际上是实现定义的)。

对于无符号类型,它们在所有平台上的表示方式相同,这意味着在所有平台上要求一致的行为不是问题。从概念上讲,与"模2宽"行为相匹配的环绕是几乎所有已知的二进制硬件平台上的自然行为。

整数溢出的C / C ++方法论是为了提供正在您正在使用的机器上最快的行为,因此在某些机器上(此处假设16位带符号整数):

32766 + 2 == -32768

但在某些机器上是:

32766 + 2 == 32767

对于其他机器,您可以具有陷阱值或CPU可以执行的任何操作。

注意Java完美定义了整数溢出,以实现"一次编写,随处运行"。

至于无符号整数-它们的大多数应用是位掩码,位域和数字操作(模运算,标识符)-正是您要使它们不确定的运算。

有些编程语言具有这样的安全措施,有些则没有:

Python 3自动将溢出的值转换为long类型(任意大整数)。

在C / C ++中,您必须自己检查溢出条件,climits(C)和limits(C ++)标头为每种类型定义了最大值和最小值。

在x86汇编中进行编程-在FLAGS和EFLAGS寄存器中,有无符号的CF(进位标志)和无符号的OF(溢出标志)以检查何时发生溢出。

为了避免溢出,许多语言还具有任意精度类型,但是操作速度较慢,因为(理论上)此类变量可能与您的内存一样大。

因为这就是语言的定义方式。它允许在更多种类的硬件(例如具有饱和算法的DSP)上更轻松地开发符合性的实现。

取决于语言。某些硬件可以使用,您也许可以在程序中利用它。

在Java中,只有无符号的int和long值,并且无论在何处运行,它们的行为都是一致的。如果将1加到Integer.MAX_VALUE,则下注Integer.MIN_VALUE(自动换行),如果从Long.MIN_VALUE中减去1,则得到Long.MAX_VALUE。

所以我不知道为什么在其他语言中未定义unsigned value的行为。

Java int和long都是有符号整数类型,必须表现得好像是2s补码。

Java中唯一的无符号整数类型是16位的char。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值