将正int8相乘并转换为uint32后溢出。

huangapple go评论90阅读模式
英文:

Overflow after multiplying positive int8s and casting to uint32

问题

我正在尝试将8位正整数相乘,并将结果转换为uint32类型。

a := int8(12)
b := uint32(a * a) // 4294967184

在上面的代码中,相乘导致了溢出。但是,如果我在相乘之前将每个int8转换为uint32/uint8,我会得到预期的结果,如下所示:

b := uint32(uint32(a) * uint32(a)) // 12

为什么我需要在相乘之前进行类型转换?

代码是否执行类似于以下方式?

tmp := a * a
b := int32(tmp)

还是还有其他原因?

英文:

I am trying to multiply 8-bit positive integers and cast the result to uint32.

a := int8(12)
b := uint32(a * a) // 4294967184

In the above code multiplying causes an overflow.
But if I cast each int8 to uint32/uint8 before multiplying, I get the expected result like below,

b := uint32(uint32(a) * uint32(a)) // 12

Why do I need to cast before multiplying?

Does the code get executed something like this?

tmp := a*a
b := int32(tmp)

Or is there something else?

答案1

得分: 1

你的问题似乎已经回答了,但为了更清楚起见:

将类型转换的语法视为函数调用的语法。参数内的表达式将被完全求值,然后传递给函数。

如果你这样写:

math.Sin(f*f)

你不会期望它等同于

math.Sin(f) * math.Sin(f)

你需要在乘法之前进行类型转换,因为在有符号的8位值中,12 * 12 不是安全的操作。

英文:

Your question seems to answer itself, but for clarity:

Think of the grammar of a type conversion as being the same as the grammar of a function call. The expression inside the parameters is fully evaluated, and then it is passed to the function.

If you do

math.Sin(f*f)

You wouldn't expect it to be equivalent to

math.Sin(f) * math.Sin(f)

You need to cast before multiplying, because 12 * 12 is not a safe operation in signed 8-bit values.

huangapple
  • 本文由 发表于 2021年7月22日 02:33:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/68474806.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定