
On Thu, Jan 5, 2017 at 2:18 PM Henson
I have one Rational number (3 + sqrt 5) and I need get the last three digits from integral part of that number.
But that number is irrational, not rational. The Haskell sqrt function from the Prelude is a method of the Floating class, so it works by default on the Double type, which is a floating point number type with a fixed-size finite representation that approximates real numbers with varying precision over a limited range.
The question is the number is arbitrary and that number always is power of n and n is between 2(Two) and 2000000000(Two billions).
I have attempted that on ghci for various values and get same result with different powers:
let x = (truncate ((3 + sqrt 5) ^ 2000000)) `mod` 1000 and result is 216.
let y = (truncate ((3 + sqrt 5) ^ 20000000)) `mod` 1000 and result is 216.
let w = (truncate ((3 + sqrt 5) ^ 200000000)) `mod` 1000 and result is 216.
let z = (truncate ((3 + sqrt 5) ^ 2000000000)) `mod` 1000 and result is 216.
The result is same for all:
216, and is incorrect because any that expressions have one exclusive value.
The Double type has a special value, Infinity, to represent (roughly) numbers too large to represent otherwise. You can get at it with a zero division: λ> 1/0 :: Double Infinity You can also get it with computations resulting in numbers too large to represent otherwise: λ> 10^308 :: Double 1.0000000000000006e308 λ> 10^309 :: Double Infinity The truncate method of the RealFrac class applied to this Infinity value can convert it to the smallest Integer value that is represented as Infinity when converted to Double: λ> truncate (1/0 :: Double) 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216 Indeed, the last three digits of the decimal representation of that number are 216. The immediately preceding Integer is indeed converted to a non-Infinity Double value: λ> fromInteger (pred (truncate (1/0 :: Double))) :: Double 1.7976931348623157e308 I believe this is all expected behavior. This article is very helpful and provides detailed explanations of many related topics: https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html --- While playing around with this, I discovered a curious difference between Float and Double. The smallest Integer that does not yield Infinity on conversion to Float is not anywhere close to the value of the expression «truncate (1/0 :: Float) :: Integer»: λ> let biggestFloat :: Integer; biggestFloat = 340282356779733661637539395458142568447 λ> fromInteger biggestFloat :: Float 3.4028235e38 λ> fromInteger (succ biggestFloat) :: Float Infinity λ> truncate (1/0 :: Float) 340282366920938463463374607431768211456 λ> truncate (1/0 :: Float) - biggestFloat 10141204801825835211973625643009 With Double, «truncate (1/0 :: Double)» is indeed the immediate successor of the largest Integer not converted to Infinity: λ> let biggestDouble :: Integer; biggestDouble = 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 λ> fromInteger biggestDouble :: Double 1.7976931348623157e308 λ> fromInteger (succ biggestDouble) :: Double Infinity λ> truncate (1/0 :: Double) - biggestDouble 1