2013-05-27 2 views
0

float2Int은 64 비트 컴퓨터의 경우 2^^622^^63 사이에서 오버플로하는 것으로 보입니다 (GHC 7.6.1을 사용하는 Intel iMac에서 사용). maxBound (Int)을 확인하려고 할 때이 문제가 나타났습니다. float2Int은 GHC에서 primop float2Int#으로 구현됩니다.float2 대문자와 소문자를 구분하여 사용하는 동작

GHCi 프롬프트 출력이 -인 경우 Intel Intel Mac에 2^^63입니다. 나는 또한 2^^63Float으로 캐스팅 해보고 오버 플로우가 사라지는지 약간의 값을 줄이기 위해 (만약 있다면 작은 반올림 오류를 설명하기 위해). 그렇지 않습니다 :

λ: maxBound :: Int 
9223372036854775807 
λ: GHC.Float.float2Int $ 2^^63 -- overflows 
-9223372036854775808 
λ: GHC.Float.float2Int $ (9223372036854775807::Float) -- now try actual value of 2^^63 
-9223372036854775808 
λ: GHC.Float.float2Int $ (9223372036854000000::Float) -- reduce it a bit 
-9223372036854775808 
λ: minBound :: Int -- overflow value is same as minBound::Int 
-9223372036854775808 
λ: GHC.Float.float2Int $ 2^^62 + 2^^61 -- works fine here 
6917529027641081856 

64 비트 Int 경계에서 오버플로가 예상되는 동작입니까? 2^^62까지 잘 작동하는 것으로 보이며 2^^622^^63 사이에서 오버플로됩니다. 나는 GHC trac를보고 어떤 버그가보고되었는지 발견하지 못했습니다. 나는 이것에 관해서 어느 쪽의 쪽이라도 그것에 관한 어떤 지위도 발견하지 않았다.

+0

많은 이론가가 사람들에게 큰 숫자는 작은 숫자와 같고 크기는 더 크다고 느끼지만 실제로는 그렇지 않다는 말을 들었습니다. AndrewC

답변

8

이것은 모두 올바른 동작입니다.

maxBound :: Int 인 내 인텔 맥

아니,해야 (2^63) - 1에 2^63이다 : 첫째, 사소한 세부 사항을 취소를 할 수 있습니다. 그 빼기는 매우 중요하므로 float2Int (2^^63)이 오버플로해야합니다.

이제 어떻게 줄일 수 있습니까? 이 점을 고려하십시오 :

Prelude GHC.Float.RealFracMethods> let a = 9223372036854775807::Float 
Prelude GHC.Float.RealFracMethods> let b = 9223372036854000000::Float 
Prelude GHC.Float.RealFracMethods> a == b 
True 

플로트는 근사치이며 사용자의 감소로 인해 플로트가 변경되지 않았습니다. 지금까지의 입력은 모두 2^63과 같습니다. 마지막 테스트로 마지막

,

> 2^^62 + 2^^61 < (2^^63 :: Float) 
True 

당신은 따라서 64 비트 Int의 범위 내에서, float로 캐스팅 할 때, 2^63보다 무언가로 표시되는 번호를 발견하고 그 결과 당신의 기대 값.

+0

@ thomas-m-dubuisson, 반올림 오류를 검사하기 위해 부동 소수점 평등을 사용하는 것이 좋은 점. – Sal

관련 문제