>백엔드 개발 >Golang >1.0을 초과할 때까지 반복적으로 0.2를 누적하고 0.3을 뺄 때 `float32`를 사용하는 Go 프로그램이 `float64`를 사용하는 유사한 프로그램이 종료되는 동안 무한 루프에 들어가는 이유는 무엇입니까?

1.0을 초과할 때까지 반복적으로 0.2를 누적하고 0.3을 뺄 때 `float32`를 사용하는 Go 프로그램이 `float64`를 사용하는 유사한 프로그램이 종료되는 동안 무한 루프에 들어가는 이유는 무엇입니까?

Linda Hamilton
Linda Hamilton원래의
2024-12-07 18:21:15284검색

Why does a Go program using `float32` enter an infinite loop while a similar program using `float64` terminates, when both accumulate 0.2 and subtract 0.3 iteratively until exceeding 1.0?

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.