Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:8x8->;由整数提升保证的16位乘法精度?_C_Standards_Language Features_Integer Promotion - Fatal编程技术网

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

C:8x8->;由整数提升保证的16位乘法精度?,c,standards,language-features,integer-promotion,C,Standards,Language Features,Integer Promotion,我试图弄清楚,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强制转换为无符号int: unsigned int foo_

我试图弄清楚,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强制转换为无符号int:

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

致以最良好的祝愿,
Craig Blome

升级是有保证的,但是如果
无符号字符
的范围符合
有符号整数
的范围,则升级为
有符号整数
类型。所以(假设它适合)从语言的角度来看

unsigned int foo_u16 = foo * 10; 
相当于

unsigned int foo_u16 = (signed) foo * 10; 
而你显然想要的是

unsigned int foo_u16 = (unsigned) foo * 10; 
如果乘法(结果)不符合
signed int
范围,则乘法的结果可能不同


如果您的编译器对其进行了不同的解释,则可能是编译器中的一个错误(同样,假设
无符号字符的范围符合
有符号整数的范围)。

只要
UCHAR_MAX
小于3277(OP的问题意味着
字符的范围为8位,因此这是正确的),然后,结果肯定适合于
有符号整数
,因此结果必须相同。另外,对
无符号整数
操作数执行乘法的另一种方法就是将常量指定为
10U
@caf:是的,您是对的。即使存在概念上的差异,结果也不会溢出。如果保证乘积不大于32767,则将两个8位
无符号字符
值相乘并赋值给一个16位
无符号整数
将产生正确的结果,而无需键入任何变量。如果乘积可以是32768到65535(例如,如果一个数乘以一个大于127的数),那么旧的编译器将正确地处理它,但现代哲学是,编译器应该可以在这种情况下自由地做任何他们想做的事,而不考虑它是否有用或合理。