Machine precision in Haskell - haskell

I googled "Haskell machine precision" and didn't find any information about how to get the machine precision in Haskell. Is there a built-in way to get it?
Otherwise I implemented it as follows (I translated some C++ code found on a serious site):
machinePrecision :: Double
machinePrecision = until isSmall half 1.0
where
isSmall :: Double -> Bool
isSmall x = 1.0 + x / 2.0 == 1.0
half :: Double -> Double
half x = x / 2.0
Is it a correct way to get the machine precision of double numbers in Haskell?

Some packages, including ieee754 and numeric-limits define a value epsilon that is the smallest representable x such that 1 and 1+x can be distinguished. That appears to be the machinePrecision value you're trying to calculate.
You can use these packages if you want, but you can also just use the two-line definition:
epsilon :: Double
epsilon = 2.2204460492503131e-16
It will never be anything else, notwithstanding any documentation in the Prelude about hypothetical Doubles that aren't IEEE754 doubles.
If you need an equivalent value for Float the definition is:
epsilon :: Float
epsilon = 1.19209290e-07
These definitions are exactly the same ones used in the ieee754 package, except in that package they're instances of a class method.
The values in Lennart Augustsson's numeric-limits package are calculated on the fly using encodeFloat and decodeFloat, a principled but "somewhat excessive" approach.
You can also use the following alternative definitions, which are equivalent:
epsilon :: Double
epsilon = 2**(-52)
epsilon :: Float
epsilon = 2**(-23)
If you are worried about portability to other Haskell implementations, start by patting yourself on the back for being one of the eight people on the planet writing Haskell for non-GHC targets, and then take comfort in the fact that there are no existing Haskell implementations whose Double is something other than an IEEE double.

Related

What is the right way to convert from Double to Fixed in Haskell?

I have some code that uses Centi for its currency type. It receives Doubles from an Excel spreadsheet using the xlsx package. I want to convert these Doubles into Centis correctly. I have tried using realToFrac, and for the most part it works, but occasionally it's out by a cent:
λ realToFrac (-1372.92 :: Double) :: Centi
-1372.93
I can guess that the problem is in the binary representation of that decimal number not being exact, and that I shouldn't be using Double to represent currency in the first place, but I don't have control of that part. So what is a fail-safe way of doing the conversion?
Maybe not the best way but one is to round to the closest integer after adjusting for the desired precision:
floatToCenti :: Double -> Centi
floatToCenti = floatToFixed
floatToFixed :: HasResolution a => Double -> Fixed a
floatToFixed x = y where
y = MkFixed (round (fromInteger (resolution y) * x))
-- reusing y as the dummy argument of resolution

Why in Haskell 0^0 == 1?

Why in Haskell 0^0 == 1 ? Why not 0^0 == 0? Or maybe should raise some error...
*Main> 0^0
1
*Main> 0**0
1.0
Thanks on advance
GHCi, version 7.10.3
It makes a bit of sense when you look at the signatures.
(^) :: (Num a, Integral b) => a -> b -> a
This one is designed to work for nonnegative integer exponents. It's likely implemented recursively, so it behaves like repeated multiplication. Thus, it makes sense that "anything to the zero power is one" is the rule that takes precedent, since we're really talking about repeated multiplication.
(^^) :: (Fractional a, Integral b) => a -> b -> a
This one is a lot like the previous one, except that it works on negative exponents too, since its base is fractional. Still, it behaves like repeated multiplication or repeated division (if the exponent is positive or negative, respectively), so again, it makes sense that repeating either of those operations zero times should result in 1, the multiplicative identity.
(**) :: Floating a => a -> a -> a
In Haskell, the floating point types generally conform to the IEEE standard, and IEEE specifically defines pow(0.0, 0.0) as 1.0. So Haskell, I imagine, is simply conforming to a standard so that it behaves consistently with other languages in this case.
Haskell does it that way because mathematics defines it that way. Math does it that way because 0⁰ = 1·0⁰, which is 1 multiplied by something else zero times, which is 1 not multiplied by anything. Mathematicians figure it makes more sense to stick to the rule that anything to the zeroth power is 1 (the nullary product) than the rule that zero to any power is zero.
This makes a lot of sense when you try to define exponents in terms of multiplications and divisions. For example, if you were trying to define ^ in Haskell, you might come up with:
(^) a b = product $ replicate b a
This is equivalent to:
(^) a b = foldr (*) 1 (replicate b a)
A list containing zero numbers is empty. The product of an empty list is 1, or else a lot of things would break, like product (xs++[]) not being equal to (product xs) * (product []).
Or if you wrote the simplest possible recursive solution:
(^) _ 0 = 1
(^) a b = a*(a^(b-1))
You would then need a special case in addition to the base and recursive cases to define 0⁰ as anthing other than 1.
PS
As #leftroundabout points out, my answer assumes we’re using discrete math. Computer scientists almost always are, and Haskell was designed by academic computer scientists.
If we are working with continuous functions on a computer, we’re necessarily doing numeric approximations. In that case, the most efficient implementation will be the one that uses the FPU of the machine we’re running on. In 2017, that will follow the IEEE standard, which says that pow( 0.0, 0.0 ) = 1.0.
It’s just slightly simpler to write and prove statements about an exponent function that follows the convention.
This is simply a law of mathematics. Any positive number raised to the 0 power is equal to 1. There should be no error
Haskell is functional programming language. Functional languages use λ-calculus in their basis. Number literals are encoded using Church encoding in λ-calculus. So if you encode 0^0 by Church and then normalize λ-term using β-reductions you will get 1 like this:
0^0 = (λn.λm.λs.λz.m n s z) (λs.λz.z) (λs.λz.z) = λs.λz.s z = 1
I think this should explain why Haskell decided to follow chosen model.

What's the difference between the classes Floating and Fractional in Haskell?

What is the difference is between the Floating and Fractional classes in Haskell?
Very roughly:
Fractional is the class of types that can represent (exactly or at least in a decent approximation) any rational number. It may ad lib also be able to represent other numbers, but that's not important.In other terms, it's just the class of number types that have a division operation; since it's a subclass of Num it follows from this that the types must contain the rational numbers.
Floating is the class of number types that are closed under limits in the Cauchy sense, i.e. complete spaces. This is necessary to do any sort of calculus. The methods of the Floating class are functions that are mathematically defined as limits, namely infinite sums (which are the limits of the sequence of partial sums of taylor series).Since you can define the real numbers as limits of sequences of rational numbers and because again Floating is a subclass of Fractional, any Floating type is able to represent (again, at least to a decent approximation) any real number.
A good way to visualise the difference is through topology: Floating types are connected spaces, i.e. they form a continuum. What this means for floating point numbers is: every value is understood as a whole interval of real numbers (because floating-point always has some uncertainty). When you lay these intervals side by side, you tile the entire real numbers (at least to ±10300) without gaps.
By contrast, some Fractional types are not connected. In particular, Rational can exactly represent all its (rational-number) values, so each value is just an “infinitely small point”. You can never cover the entire real line with such points, and you can not compute functions like sin or log since the result of these functions is usually a non-rational real number.
It's worth pondering a bit what this “decent approximation” means. The Haskell standard doesn't define this. This story about every floating point number representing a whole interval of real numbers captures it quite well IMO. More generally, we might say: Num/Fractional/Floating are the classes of types that represent equivalance classes of integer/rational/real numbers. In fact, these classes need not even be “small” intervals: in particular the finite types like Word32 or the standard Int can be understood in a modular arithmetic sense, manifesting in results like (2^70 :: Int) == 0, i.e. the equivalence classes are then numbers spaces by a multiple of 264.
In cases like Integer or Rational, the equivalence classes actually contain only a single element, i.e. the numbers are represented exactly. For real numbers, this is actually also possible, but much more tricky, it's called exact real arithmetic. There are libraries such as aern that do this.
The definitions of Fractional and Floating can be found in the documentation of the Prelude:
class Num a => Fractional a where
(/) :: a -> a -> a
recip :: a -> a
fromRational :: Rational -> a
Fractional numbers, supporting real division.
[...]
class Fractional a => Floating a where
pi :: a
exp :: a -> a
log :: a -> a
sqrt :: a -> a
(**) :: a -> a -> a
logBase :: a -> a -> a
sin :: a -> a
cos :: a -> a
tan :: a -> a
asin :: a -> a
acos :: a -> a
atan :: a -> a
sinh :: a -> a
cosh :: a -> a
tanh :: a -> a
asinh :: a -> a
acosh :: a -> a
atanh :: a -> a
Trigonometric and hyperbolic functions and related functions.
[...]
So to translate that into English: A Fractional is any kind of number for which I can define a division:
(/) :: Fractional a => a -> a -> a
That can for instance be the case for floating point numbers, but also for fractions (where a fraction has a numerator and denominator). This is not the case for Int because if dividing an Int by an Int does not always produce an Int (well technically floating point division on a computer is not exact, but that is another story).
A subset of Fractional numbers are Floating numbers where trigonometric are defined. It is for instance impossible that the sin of a fraction always produces a fraction: a sin is defined as an sum over an infinite sequence. Only for a very limited number of cases (like sin 0) it holds. Basically the only numbers on a computer for which trigonometric are defined (approximatively) are floating point numbers.

Type conversion and equality behaviour

I'm new to Haskell, and just stumbled across this problem. I'm trying to figure out an explaination, but I don't have enough experience with Haskell types to be sure.
The function:
mystery :: Int -> Int -> Float -> Bool
mystery x y z = not ((x==y) && ((fromIntegral y) == z ))
behaves as it seems like it would. It's basically checking if the values are all NOT equal, but doing a type conversion from an Integral y to make sure it can be compared with z
If this is true, then why does:
case1 = do
if mystery 1 1 1.00000001 -- a very small number
then putStrLn "True"
else putStrLn "False"
Print False (ie. The values are all equal, so 1 == 1 == 1.00000001) whereas:
case2 = do
if mystery 1 1 1.0000001 -- a larger number
then putStrLn "True"
else putStrLn "False"
Prints True? (ie. The values are not all equal)
I know it likely has something to do with precision, but I don't get it. Any help is greatly appreciated.
Floating point operations are generally approximate, and == is not one of the exceptions to that rule. Single-precision floating point (Float) runs out of precision pretty quickly, while the more-generally-useful double-precision floating point (Double) has some more. In either case, your decimal fraction will be converted approximately to binary floating point, and then the equality test will also be approximate. General rule: floating point representations are not numbers, and they are not even legitimate instances of the Eq class. If you want to use them, you need to pay attention to their limitations.
In this case, you need to think about when you want to consider the integer equal to the floating point representation. You may or may not want to rely directly on the built-in comparison and rounding operations.
For some of the details you'll have to think about, check out the classic What Every Computer Scientist Should Know About Floating-Point Arithmetic, and don't skip the corrections and updates in the footnotes.
Your code can be simplified to:
> (1.00000001 :: Float) == 1
True
Looks like Float simply doesn't have enough precision to store the last bits of 1.00000001, so it gets truncated to plain 1.
1/10^n can't be represented in base2 floating point (IEEE 754), so the value is probably truncated.
Semantically, for integer comparison it's probably more accurate to truncate the floating point value.
mystery :: Int -> Int -> Float -> Bool
mystery x y z = not (x == y && y == truncate z)

Haskell datatype conversion problems

I am currently learning Haskell and have been writing a couple of very simple programs to practice as I go along. One of these programs is the one I have bellow:
import System.IO
main = do
putStrLn "Give me year: "
y <- getLine
let res = show . calcPop $ read y
putStrLn ("Population in " ++ y ++ " will be " ++ res)
pop :: Float
pop = 307357870.0
secInYear :: Float
secInYear = 365.0 * 24.0 * 60.0 * 60.0
bRate :: Float
bRate = secInYear / 7.0
dRate :: Float
dRate = secInYear / 13.0
iRate :: Float
iRate = secInYear / 35.0
calcPop :: Float -> Float
calcPop year = let years = year - 2010 in (years*bRate + years*iRate + pop - years*dRate)
What it does is take a year after 2010 and calculate the estimated population in that year, and as it is right now it works fine and all except that as you may have noticed EVERY single number is cast as a float. Now it is pretty ridiculous to do this since there is no reason to have the current population, the number of seconds in a year or the year itself for that matter as anything but ints, unfortunately though when I had it that way I was getting compiler error with the / function saying something about fractional int and with the * function saying it inferred a float as the first parameter. Now I had understood that Haskell like other languages when encountering operations involving ints and floats would just change the int to act like a float which aperantly didn't happen here. Could someone explain why I was getting these errors and how I can get ints and floats to cooperate since evidently I still don't have a good enough grasp of the Haskell type system to do it myself?
Haskell types are strict; it never automatically converts a type for you, except that integer literals are automatically wrapped in fromIntegral. Instead, you may want to use more type-appropriate operations such as `div` when you only need to deal with Int/Integer, and fromIntegral to promote to Float or Double when needed.
(Syntax note: `function` converts a prefix function into an infix operator.)
For integer division in Haskell you use div or quot.
From the Haskell 98 language report:
An integer literal represents the
application of the function
fromInteger to the appropriate value
of type Integer. Similarly, a floating
point literal stands for an
application of fromRational to a value
of type Rational (that is, Ratio
Integer).
This means a "7" in the source code becomes "(fromInteger 7)" and "1.5" becomes "(fromRational (3 Ratio.% 2))". The numerical operations such as (+) and (/) have type signatures like "a->a->a" meaning they two arguments of perfectly identical types and return the same type as given. These standard operators can never do things like add a Float to an Int. You can write a (fromIntegral) to try and promote an Int-like-type to things like a Double or Float.

Resources