C:8x8 - > 16位乘法精度由整数提升保证?

Cra*_*ome 5 c standards language-features integer-promotion

我试图找出C标准(C90,虽然我正在使用Derek Jones的注释C99书),但我保证不会丢失精度乘以两个无符号8位值并存储到16位结果.示例声明如下:

unsigned char foo;
unsigned int foo_u16 = foo * 10;
Run Code Online (Sandbox Code Playgroud)

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

unsigned int foo_u16 = (unsigned int)foo * 10;
Run Code Online (Sandbox Code Playgroud)

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

此致,Craig Blome

AnT*_*AnT 5

促销是有保证的,但促销是在符合signed int范围的情况下键入.所以(假设它适合)从语言的角度来看你的unsigned charsigned int

unsigned int foo_u16 = foo * 10; 
Run Code Online (Sandbox Code Playgroud)

相当于

unsigned int foo_u16 = (signed) foo * 10; 
Run Code Online (Sandbox Code Playgroud)

而你显然想要的是

unsigned int foo_u16 = (unsigned) foo * 10; 
Run Code Online (Sandbox Code Playgroud)

如果(结果)不适合该signed int范围,则乘法的结果可以不同.

如果你的编译器以不同的方式解释它,它可能是编译器中的一个错误(同样,在假设范围unsigned char适合范围内signed int).