[python] 파이썬에서 왜 1 // 0.01 == 99입니까?

나는 이것이 고전적인 부동 소수점 정밀도 질문이라고 생각하지만, 1//0.01파이썬 3.7.5 수율로 실행 하면서이 결과를 머리로 감싸려고합니다.99 .

나는 그것이 예상되는 결과라고 생각하지만, int(1/f)오히려 사용 하기보다 안전한시기를 결정할 수있는 방법 이 1//f있습니까?



답변

이것이 1//0.01실수로 0.01나누면 정확히 100입니다. 부동 소수점 근사값 은 1/100보다 약간 크므로 몫이 100보다 약간 작다는 의미입니다.이 값은 99입니다. ~ 99


답변

이 결과의 이유는 사용자가 말한 것과 같으며 부동 소수점 수학이 손상 되었습니까?에 설명되어 있습니다 . 그리고 다른 많은 유사한 Q & A.

분자와 분모의 소수점 이하 자릿수를 알면 더 신뢰할 수있는 방법은 먼저 그 숫자를 곱하여 정수로 처리 한 다음 정수 나누기를 수행하는 것입니다.

따라서 귀하의 경우 1//0.01먼저 1*100//(0.01*100)100 으로 변환해야합니다 .

더 극단적 인 경우에도 “예기치 않은”결과를 얻을 수 있습니다. round정수 나누기를 수행하기 전에 분자와 분모에 대한 호출 을 추가해야 할 수도 있습니다 .

1 * 100000000000 // round(0.00000000001 * 100000000000)

그러나,이 고정 소수점 (돈, 센트) 작업에 대한 경우, 다음과 같은 센트 작업을 고려 단위 그래서 모든 연산이 정수 연산으로 수행 할 수 있음을, 그리고 에만 수행 할 때 주요 통화 단위 (달러)에서 /로 변환 I / O

또는 다음과 같이 소수 자릿수에 라이브러리를 사용하십시오 .

… 올바른 반올림 십진 부동 소수점 산술을 지원합니다.

from decimal import Decimal
cent = Decimal(1) / Decimal(100) # Contrary to floating point, this is exactly 0.01
print (Decimal(1) // cent) # 100


답변

당신이 고려해야 할 것은 즉 //는 IS floor연산자와 당신이 99에서 100으로 하락하는 동일한 확률을 가지고있는 것처럼 같은 당신이 먼저 (*) (작업이되기 때문에 생각해야 100 ± epsilon으로epsilon>0 제공되는 정확히 100.00을 얻을 수있는 기회 ..0은 매우 낮습니다.)

실제로 마이너스 부호로 똑같이 볼 수 있습니다.

>>> 1//.01
99.0
>>> -1//.01
-100.0

그리고 당신은 (놀랍지 않은) 사람이어야합니다.

반면에 int(-1/.01)먼저 나누기를 수행 한 다음 바닥이 아니라 0쪽으로int()립니다 . 그런 경우에

>>> 1/.01
100.0
>>> -1/.01
-100.0

그 후,

>>> int(1/.01)
100
>>> int(-1/.01)
-100

반올림하면이 연산자에 대한 예상 결과가 다시 나타납니다.

(*) 나는 확률이 같다고 말하는 것이 아니라, 당신이 얻는 것을 추정하는 부동 산술로 그러한 계산을 수행 할 때 선험적으로 말하는 것입니다.


답변

부동 소수점 숫자는 대부분의 10 진수를 정확하게 표현할 수 없으므로 부동 소수점 리터럴을 입력하면 실제로 해당 리터럴의 근사값을 얻습니다. 근사값은 입력 한 숫자보다 크거나 작을 수 있습니다.

부동 소수점 숫자를 10 진수 또는 분수로 캐스트하여 정확한 값을 볼 수 있습니다.

>>> from decimal import Decimal
>>> Decimal(0.01)
Decimal('0.01000000000000000020816681711721685132943093776702880859375')
>>> from fractions import Fractio
>>> Fraction(0.01)
Fraction(5764607523034235, 576460752303423488) 

분수 유형을 사용하여 부정확 한 리터럴로 인한 오류를 찾을 수 있습니다.

>>> float((Fraction(1)/Fraction(0.01)) - 100)
-2.0816681711721685e-15

우리는 또한 numpy에서 nextafter를 사용하여 100 정도의 세부 배정도 부동 소수점 숫자가 얼마나되는지 알아낼 수 있습니다.

>>> from numpy import nextafter
>>> nextafter(100,0)-100
-1.4210854715202004e-14

이것으로부터 우리는 가장 가까운 부동 소수점 숫자 1/0.01000000000000000020816681711721685132943093776702880859375가 실제로 100이라는 것을 추측 할 수 있습니다 .

차이 1//0.01int(1/0.01)반올림된다. 1 // 0.01은 정확한 결과를 한 번에 다음 정수로 내림합니다. 결과는 99입니다.

반면에 int (1 / 0.01)은 두 단계로 반올림됩니다. 먼저 결과를 가장 가까운 배정 밀도 부동 소수점 숫자 (정확히 100 임)로 반올림 한 다음 부동 소수점 숫자를 다음 정수로 반올림합니다. 다시 정확히 100).


답변

다음을 실행하면

from decimal import *

num = Decimal(1) / Decimal(0.01)
print(num)

출력은 다음과 같습니다.

99.99999999999999791833182883

이 아래로 반올림 있도록 내부적으로, 표현 어떻게입니다 //줄 것이다99


답변