2010-04-22 107 views
5

我试图弄清楚C标准(C90,虽然我正在关闭Derek Jones注释的C99书),但我保证不会丢失精度乘以两个无符号的8位值并存储到16位结果。一个例子语句如下:C:8x8 - > 16位乘以整数升级的精度保证?

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

我们的Keil 8051编译器(目前V7.50)将产生,其存储在MSB B寄存器和LSB中的储液器的MUL指令AB。如果我投FOO到unsigned int的第一:

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

那么编译器正确决定我一个unsigned int的存在,并产生昂贵的呼叫到16×16位整数乘法程序。我想无疑地辩解说这种防御措施是没有必要的。当我读到6.3.1.1中描述的整数升级时,第一行的效果应该如同foo和10被提升为unsigned int,执行乘法,结果存储为foo_u16中的unsigned int。如果编译器知道没有精度损失的8×8-> 16位乘法的指令,那么更好;但精度有保证。我正确阅读这个吗?

最好的问候, 克雷格BLOME

回答

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的范围)。

+1

只要'UCHAR_MAX'小于3277(并且OP的问题意味着'char'是8位,所以这是真的),那么结果肯定会适合'signed int',因此结果必须是一样。 – caf 2010-04-23 00:59:49

+0

另外,在'unsigned int'操作数上完成乘法的另一种方法就是将常量指定为'10U'。 – caf 2010-04-23 01:02:28

+0

@caf:是的,你说得对。即使有概念上的差异,结果也不应该溢出。 – AnT 2010-04-23 01:28:29