con*_*roy 26 c c++ binary casting
在C或C++中,可以说size_t(无符号整数数据类型)可以容纳的最大数量与向该数据类型强制转换-1相同.例如,请参阅size_t的无效值
为什么?
我的意思是,(谈论32位整数)AFAIK最重要的位保持有符号数据类型的符号(即,位0x80000000形成负数).那么,1是0x00000001 .. 0x7FFFFFFFF是int数据类型可以容纳的最大正数.
然后,AFAIK的-1 int的二进制表示应该是0x80000001(也许我错了).为什么/如何将这个二进制值转换为完全不同的任何东西(0xFFFFFFFF)时将int转换为unsigned?或..如何形成0xFFFFFFFF的二进制-1?
我毫不怀疑在C :((unsigned int)-1)== 0xFFFFFFFF或((int)0xFFFFFFFF)== -1同样真实而不是1 + 1 == 2,我只是想知道为什么.
Alo*_*hal 48
C和C++可以在许多不同的体系结构和机器类型上运行.因此,它们可以有不同的数字表示:两个补码,而Ones的补码是最常见的.通常,您不应该依赖程序中的特定表示.
对于无符号整数类型(size_t作为其中之一),C标准(我认为也是C++标准)指定了精确的溢出规则.简而言之,如果SIZE_MAX是类型的最大值size_t,那么表达式
(size_t) (SIZE_MAX + 1)
保证是0,因此,你可以肯定(size_t) -1等于SIZE_MAX.对于其他无符号类型也是如此.
请注意,以上情况属实:
此外,上述意味着您不能依赖签名类型的特定表示.
编辑:为了回答一些评论:
假设我们有一个代码片段,如:
int i = -1;
long j = i;
在分配中有一个类型转换j.假设int和long具有不同的尺寸(最[所有?] 64位系统),位模式在存储器位置为i与j将要不同的,因为它们具有不同的尺寸.编译器可以确保值的i和j是-1.
同样,当我们这样做时:
size_t s = (size_t) -1
正在进行类型转换.该-1是类型int.它有一个位模式,但这与此示例无关,因为当转换由于强制转换而size_t发生时,编译器将根据类型的规则(在本例中)转换该值size_t.因此,即使int并且size_t具有不同的尺寸,该标准也保证了s上面存储的值将是size_t可以采用的最大值.
如果我们这样做:
long j = LONG_MAX;
int i = j;
如果LONG_MAX大于INT_MAX,则值为i实现定义(C89,第3.2.1.2节).
Mar*_*som 26
它被称为二补.要得到一个负数,反转所有的位然后加1.所以要将1转换为-1,将其反转为0xFFFFFFFE,然后加1以使其为0xFFFFFFFF.
至于为什么这样做,维基百科说:
二进制补码系统的优点是不需要加法和减法电路检查操作数的符号以确定是加或减.该属性使系统更易于实现,并且能够轻松处理更高精度的算术.
关于为什么(unsigned)-1给出最大可能无符号值的第一个问题只是偶然地与两个补码相关.-1转换为无符号类型的原因给出了该类型可能的最大值,因为标准表示无符号类型"遵循算术模2 n的定律,其中n是该特定大小的值表示中的位数整数."
现在,对于2的补码,最大可能的无符号值和-1的表示恰好相同 - 但即使硬件使用另一种表示(例如1的补码或符号/幅度),将-1转换为无符号类型必须仍然为该类型产生最大可能的值.
| 归档时间: | 
 | 
| 查看次数: | 65131 次 | 
| 最近记录: |