C:8x8->整数提升保证 16 位乘法精度?
我试图弄清楚 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,执行乘法,并将结果存储为 foo_u16 中的 unsigned int。如果编译器知道一条指令可以执行 8x8->16 位乘法而不损失精度,那就更好了;但精度有保证。我读得正确吗?
此致, 克雷格·布洛姆
I'm trying to figure out if the C Standard (C90, though I'm working off Derek Jones' annotated C99 book) guarantees that I will not lose precision multiplying two unsigned 8-bit values and storing to a 16-bit result. An example statement is as follows:
unsigned char foo;
unsigned int foo_u16 = foo * 10;
Our Keil 8051 compiler (v7.50 at present) will generate a MUL AB instruction which stores the MSB in the B register and the LSB in the accumulator. If I cast foo to a unsigned int first:
unsigned int foo_u16 = (unsigned int)foo * 10;
then the compiler correctly decides I want a unsigned int there and generates an expensive call to a 16x16 bit integer multiply routine. I would like to argue beyond reasonable doubt that this defensive measure is not necessary. As I read the integer promotions described in 6.3.1.1, the effect of the first line shall be as if foo and 10 were promoted to unsigned int, the multiplication performed, and the result stored as unsigned int in foo_u16. If the compiler knows an instruction that does 8x8->16 bit multiplications without loss of precision, so much the better; but the precision is guaranteed. Am I reading this correctly?
Best regards,
Craig Blome
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
提升是有保证的,但如果
unsigned char
的范围符合signed int
的范围,则提升为signed int
类型。因此(假设它适合)从语言的角度来看,您相当于,
而您显然想要的是
如果乘法(结果)不适合
signed int 范围。
如果您的编译器对它的解释不同,则可能是编译器中的错误(同样,假设
unsigned char
的范围适合signed int
的范围)。The promotion is guaranteed, but the promotion is made to
signed int
type if the range ofunsigned char
fits into the range ofsigned int
. So (assuming it fits) from the language point of view youris equivalent to
while what you apparently want is
The result of the multiplication can be different if it (the result) doesn't fit into the
signed int
range.If your compiler interprets it differently, it could be a bug in the compiler (again, under the assumption that range of
unsigned char
fits into the range ofsigned int
).