Go의 부동 소수점 정밀도 차이점: float32와 float64
Go에서 부동 소수점 값은 float32 또는 float64로 표시될 수 있습니다. , 다양한 수준의 정밀도로. 최근 실험에서 프로그램은 float32 및 float64 유형을 모두 사용할 때 부동 소수점 오류를 보여주었습니다.
프로그램은 부동 소수점 값 0.2를 여러 번 누적하고 값이 1.0을 초과할 때까지 각 반복마다 0.3을 뺍니다. float64를 사용하면 프로그램은 54번 반복 후 1.000000e 00을 출력하는데 이는 C에서 동일한 프로그램의 동작과 유사합니다(double을 사용하는 경우).
그러나 Go 프로그램에서 float32를 사용하면 무한대에 들어갑니다. 고리. 이러한 불일치는 Go와 C가 float32 표현을 처리하는 다양한 방식에서 발생합니다.
부동 소수점 표현 검사
math.Float32bits 및 math.Float64bits 함수를 사용하여 Go가 10진수 값을 IEEE 754 바이너리로 표현하는 방법을 관찰할 수 있습니다. 값:
float32(0.1): 00111101110011001100110011001101 float32(0.2): 00111110010011001100110011001101 float32(0.3): 00111110100110011001100110011010 float64(0.1): 0011111110111001100110011001100110011001100110011001100110011010 float64(0.2): 0011111111001001100110011001100110011001100110011001100110011010 float64(0.3): 0011111111010011001100110011001100110011001100110011001100110011
float32 정밀도 분석
이 이진수 값을 십진수로 변환하면 float32를 사용하는 Go 프로그램에서 a의 초기 값은 다음과 같습니다.
0.20000000298023224 + 0.10000000149011612 - 0.30000001192092896 = -7.4505806e-9
이 음수 값은 루프가 도달하는 것을 방지합니다. 1.0.
C 구현 차이점
C에서는 float 상수를 처리하는 방법의 차이로 인해 동작이 다릅니다. Go는 가장 가까운 이진 표현으로 0.1에 가까워지는 반면 C는 마지막 비트를 자를 수 있습니다.
Go: 00111101110011001100110011001101 => 0.10000000149011612 C(?): 00111101110011001100110011001100 => 0.09999999403953552
결과적으로 C는 0.1을 더 정확하게 표현하도록 허용하여 부동 소수점 루프에 대해 다른 결과를 가져옵니다. float32를 사용할 때.
위 내용은 1.0을 초과할 때까지 반복적으로 0.2를 누적하고 0.3을 뺄 때 `float32`를 사용하는 Go 프로그램이 `float64`를 사용하는 유사한 프로그램이 종료되는 동안 무한 루프에 들어가는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!