5

我试图弄清楚 C 标准(C90,虽然我正在研究 Derek Jones 的带注释的 C99 书)是否保证我不会丢失将两个无符号 8 位值相乘并存储到 16 位结果的精度。一个示例语句如下:

unsigned char foo;
unsigned int foo_u16 = foo * 10;

我们的 Keil 8051 编译器(目前为 v7.50)将生成一条 MUL AB 指令,该指令将 MSB 存储在 B 寄存器中,将 LSB 存储在累加器中。如果我首先将 foo 转换为 unsigned int :

unsigned int foo_u16 = (unsigned int)foo * 10;

然后编译器正确地决定我需要一个 unsigned int 并生成对 16x16 位整数乘法例程的昂贵调用。我想毫无疑问地争辩说,这种防御措施是不必要的。当我阅读 6.3.1.1 中描述的整数提升时,第一行的效果应该就像 foo 和 10 提升为 unsigned int,执行乘法,并将结果作为 unsigned int 存储在 foo_u16 中。如果编译器知道执行 8x8->16 位乘法而不损失精度的指令,那就更好了;但精度是有保证的。我读对了吗?

最好的问候,克雷格布洛姆

4

1 回答 1

5

signed int促销是有保证的,但如果 的范围unsigned char符合 的范围,则促销是按类型进行的signed int。所以(假设它适合)从语言的角度来看你

unsigned int foo_u16 = foo * 10; 

相当于

unsigned int foo_u16 = (signed) foo * 10; 

而你显然想要的是

unsigned int foo_u16 = (unsigned) foo * 10; 

如果乘法(结果)不适合该signed int范围,则乘法的结果可能会有所不同。

如果您的编译器对它的解释不同,则可能是编译器中的错误(同样,假设范围unsigned char适合范围signed int)。

于 2010-04-22T18:59:11.187 回答