英文:
Golang losing precision while converting int to float32
问题
有人可以解释一下为什么下面的转换会失去精度吗?
func main() {
var a int32 = 1273478460
fmt.Println(a)
fmt.Printf("%f \n", float64(a)) // 1273478460.000000,这是正确的数字
fmt.Printf("%f \n", float32(a)) // 1273478400.000000,这是错误的数字
}
英文:
Can anyone explain why the following conversion loses precision?
func main() {
var a int32 = 1273478460
fmt.Println(a)
fmt.Printf("%f \n", float64(a)) // 1273478460.000000, this is right number
fmt.Printf("%f \n", float32(a)) // 1273478400.000000, this is wrong number
}
答案1
得分: 0
浮点数在精度和范围之间进行了权衡。IEEE-754单精度(32位)浮点数占用1个完整的32位字(自然而然)。它具有:
- 1个符号位,
- 8位指数,
- 23位尾数
在单精度浮点数中,可以安全表示的最大整数(由于尾数的表示方式,提供了一个额外的隐含位精度)是2的24次方(十进制为16,777,216);可以安全表示的最小整数是-(2的24次方)(十进制为-16,777,216)。这给出了33,554,433个整数的范围。
对于双精度浮点数(1个符号位,11位指数,52位尾数),情况类似:
- 最小安全整数是-(2的53次方)(十进制为9,007,199,254,740,992)
- 最大安全整数是2的53次方(十进制为9,007,199,254,740,992)
另请参阅《每个计算机科学家都应该了解的浮点运算知识》(What Every Computer Scientist Should Know About Floating-Point Arithmetic)。发表于《ACM Computing Surveys》,第23卷,第1期,1991年3月。这是必读的资料。
英文:
Floating point trades precision for range. An IEEE-754 single precision (32-bit) float occupies 1 full 32-bit word (naturally). It has
- 1 sign bit,
- 8-bit exponent,
- 23-bit mantissa
The largest integer than can be safely represented in a single precision float (due to the way the mantissa is represented, giving an implicit extra bit of precision) is 2<sup>24</sup> (decimal 16,777,216); the smallest integer that can be safely represented is - (2<sup>24</sup>) (decimal -16,777,216). That gives a range of 33,554,433 integers.
For double precision floats (1 sign bit, 11-bit exponent, 52-bit mantissa) it's similar:
- min safe integer is - (2<sup>53)</sup> (decimal 9,007,199,254,740,992)
- max safe integer is 2<sup>53</sup> (decimal 9,007,199,254,740,992)
See also What Every Computer Scientist Should Know About Floating-Point Arithmetic. Published in ACM Computing Surveys, Vol 23, Number 1, March 1991. Essential reading.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论