环绕的解释在C符号和无符号变量? [英] Wrap around explanation for signed and unsigned variables in C?

查看:243
本文介绍了环绕的解释在C符号和无符号变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读取C规格位无符号变量(特别的无符号的短整型的)执行一些所谓的环绕的整数溢出,虽然我无法找到任何东西上除了我留下的未定义行为签署的变量。我的教授告诉我,他们的价值观也得到缠。(也许他只是意味着GCC)我以为只是位会被截断,我只剩下位给我一些奇怪的价值?所以,任何人都可以解释什么环绕是和它是如何从刚截断位不同。

I read a bit in C spec that unsigned variables( in particular unsigned short int) perform some so called wrap around on integer overflow although I couldn't find anything on signed variables except that i left with undefined behavior. My professor told me their values also get wrapped around.( maybe he just meant gcc ) I thought the bits just get truncated and the bits I left with give me some weird value?! So, can anyone explain what wrap around is and how is it different from just truncating bits.

推荐答案

符号整型变量没有在C语言中回绕的行为。在算术计算有符号整数溢出产生的未定义行为的。注意:BTW你提到的GCC编译器被称为实施的严溢语义的的优化,这意味着它需要通过这种不确定的行为的情况下提供了自由的优势:GCC编译器假定符号整数永远环绕。这意味着,实际上GCC恰好是在你的编译器中的一个不能的依赖符号整数类型的环绕式的行为。

Signed integer variables do not have wrap-around behavior in C language. Signed integer overflow during arithmetic computations produces undefined behavior. Note BTW that GCC compiler you mentioned is known for implementing strict overflow semantics in optimizations, meaning that it takes advantage of the freedom provided by such undefined behavior situations: GCC compiler assumes that signed integer values never wrap around. That means that GCC actually happens to be one of the compilers in which you cannot rely on wrap-around behavior of signed integer types.

例如,GCC编译器可以假设变量 INT I 以下条件

For example, GCC compiler can assume that for variable int i the following condition

if (i > 0 && i + 1 > 0)

等同于一个单纯的

is equivalent to a mere

if (i > 0)

这是什么严格溢出语义的意思。

无符号整数类型实现模运算。模数等于 2 ^ N ,其中 N 是位的的转口货值presentation数类型。出于这个原因无符号整型确实出现环绕在溢出。

Unsigned integer types implement modulo arithmetic. The modulo is equal 2^N where N is the number of bits in the value representation of the type. For this reason unsigned integer types do indeed appear to wrap around on overflow.

不过,C语言从来没有在执行域算术计算比 INT / unsigned int类型小。键入无符号的短整型,你在你的问题提通常会被提升到键入 INT 在出厂前pressions任何计算开始(假设无符号短的范围适合 INT 的范围)。这意味着1)与计算无符号的短整型将在 INT 域pformed $ P $,与溢出发生时, INT 溢出,2)这样的计算过程中的溢出会导致不确定的行为,而不是环绕式的行为。

However, C language never performs arithmetic computations in domains smaller than that of int/unsigned int. Type unsigned short int that you mention in your question will typically be promoted to type int in expressions before any computations begin (assuming that the range of unsigned short fits into the range of int). Which means that 1) the computations with unsigned short int will be preformed in the domain of int, with overflow happening when int overflows, 2) overflow during such computations will lead to undefined behavior, not to wrap-around behavior.

例如,这code产生回绕

For example, this code produces a wrap around

unsigned i = USHRT_MAX;
i *= INT_MAX; /* <- unsigned arithmetic, overflows, wraps around */

而这code

unsigned short i = USHRT_MAX;
i *= INT_MAX; /* <- signed arithmetic, overflows, produces undefined behavior */

将导致不确定的行为。

leads to undefined behavior.

如果没有 INT 溢出发生,结果被转换回无符号的短整型类型,又是通过模 2 ^ N ,将出现仿佛价值缠减少。

If no int overflow happens and the result is converted back to an unsigned short int type, it is again reduced by modulo 2^N, which will appear as if the value has wrapped around.

这篇关于环绕的解释在C符号和无符号变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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