我读了here,那是:
根据C99§6.3.1.4脚注50:
当整数类型的值为时执行的剩余操作 当值为real时,不需要执行转换为无符号类型 浮动类型转换为无符号类型。因此,范围 便携式实数浮点值为(-1,Utype_MAX + 1)。
现在,我感兴趣的是: C ++ 03 !之间的细微差别:
double d1 = 257;
double d2 = -2;
unsigned char c1 = d1; // undefined, since d1 > 256
unsigned char c2 = d2; // undefined, since d2 < -1
和
double d1 = 257;
double d2 = -2;
unsigned int i1 = d1; // defined, since d1 <= 2^32
unsigned int i2 = d2; // still undefined, right?
unsigned char c1 = i1; // defined, modulo 2^8, so c1 == 1
因此第一个c1
和第二个c1
不能保证比较相等,对吗?上面的引文是否也适用于C ++ 03,还是有其他规则?
修改
并且定义了c2
(对于-(2^31-1) <= d2 < 0
)这是必要的吗?
double d2 = -2;
int sign = (d2<0 ? -1 : 1);
unsigned char c2 = sign * (int)abs(d2); // defined, c2 == 2^8-2 ?
答案 0 :(得分:2)
是的,同样的规则适用于C ++。 (但是,我将遵循2010年的C ++标准草案; C ++ 2003已经过时了。而且,我使用的是N3092,而不是官方草案。)第4.9条第1款说“如果截断值不能,则行为未定义以目的地类型表示。“
无符号整数运算确实包装;它以模数1的最大值模数执行。但是,这适用于类型内的算术。从浮点到无符号整数的转换不属于此。
您转换d2
的代码似乎比必要的更复杂。如果d2
在int
的范围内,您只需使用unsigned char c2 = (int) d2;
。 (尽管从int
到unsigned int
的转换也在同构无符号整数运算之外,但此转换的规范确实说它的减少方式与无符号整数运算相同。)