发生整数溢出时无符号整数和有符号整数的行为差异 [英] Difference in behaviour of unsigned and signed integer when integer overflow occurs

查看:65
本文介绍了发生整数溢出时无符号整数和有符号整数的行为差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在维基百科上阅读这篇关于整数溢出

Reading this article on wikipedia about Integer Overflow

我不太明白为什么有符号整数溢出导致未定义行为但无符号整数溢出导致回绕的部分.为什么它们的行为有区别?

I dont quite understand the part why overflowing of signed integers causes undefined behaviour but overflowing of unsigned integers causes wrapping around.Why is there a difference in their behaviour?

另一个问题:编程语言通常有防止整数溢出的保护措施吗?

Another questions: Do programming languages in general have any safeguards against integer overflow?

推荐答案

差异的主要理由是 C 和 C++ 语言规范允许实现使用以下三种不同的有符号整数表示形式之一

The primary rationale for the difference is the fact that C and C++ language specification allows the implementation to use one of the following three different signed integer representations

  1. 1 的补码
  2. 2 的补码
  3. 有符号幅度

如果语言规范在有符号溢出的情况下强制执行某些特定行为(即偏爱上述表示中的一种而不是其他两种),它将强制基于两种非偏爱表示的平台实现重"有符号整数算法.这将成为必要,因为此类平台的自然机器级行为与语言标准要求的行为不匹配.这些实现必须不断观察签名溢出并调整结果以符合标准要求.

If the language specification mandated some specific behavior in case of signed overflow (i.e. favored one of the above representations over the other two), it would force platforms based on two non-favored representations to implement "heavy" signed integer arithmetic. It would become necessary, since the natural machine-level behavior of such platforms would not match the behavior required by the language standard. These implementation would have to constantly watch for signed overflow and adjust the results to match the standard requirements.

这将严重降低使用不受欢迎的有符号表示的平台上有符号整数算法的性能,当然,这在 C 和 C++ 等语言中是完全不可接受的,这些语言旨在尽可能接近涉及整数运算等基本运算时的底层硬件.

That would severely degrade the performance of signed integer arithmetic on platforms that use non-favored signed representations, which is, of course, completely unacceptable in such languages as C and C++, which are designed to be as close as possible to the underlying hardware when it comes to such basic operations as integer arithmetic.

行为是 undefined(与 *unspecified 相对)的原因是因为有些平台会在整数运算过程中出现有符号溢出时故意生成硬件异常.请注意,行为未定义仅用于算术运算,通常由机器执行.对于值转换,有符号溢出不会产生未定义行为(该行为实际上是实现定义的).

The reason the behavior is undefined (as opposed to *unspecified") is because there are platforms out there which deliberately generate hardware exceptions in case of signed overflow during integer arithmetic. Note, that the behavior is undefined only for arithmetic operations, which are typically performed by the machine. For value conversions signed overflow does not produce undefined behavior (the behavior is actually implementation-defined).

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

As for unsigned types, they are represented identically on all platforms, which means that requiring consistent behavior across all platforms is not a problem. The wraparound that conceptually matches the "modulo 2^width" behavior is the natural behavior on virtually all known binary hardware platforms.

这篇关于发生整数溢出时无符号整数和有符号整数的行为差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆