Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 642
joseabp91 Avatar asked Jan 31 '17 17:01

joseabp91


People also ask

What is fractional in Haskell?

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.

What is a float in Haskell?

Introduction. Haskell has two types for floating-point numbers, namely Float (single-precisionsingle-precisionSingle-precision floating-point format (sometimes called FP32 or float32) is a computer number format, usually occupying 32 bits in computer memory; it represents a wide dynamic range of numeric values by using a floating radix point.https://en.wikipedia.org › wiki › Single-precision_floating-poi...Single-precision floating-point format - Wikipedia) and Double (double-precision). Floating-point numbers can be represented in two ways. First, using a decimal point: 2.0 33.873 -8.3377. Second, by means of the so-called scientific notation: 33.61e6 3.7e-2 -3.7e2.

Is float a fractional number?

A float is a rational number expressed in floating-point format, usually to base 10 or decimal. What does that mean? Consider the number 110. We can write it as 1.1 x 102, where the decimal point one digit before the end indicates that that first number is really the fraction 11 / 10.

Can floats store fractional numbers?

Floating-point numbers do not store fractions generally. Typically, a single-precision floating-pointsingle-precision floating-pointSingle-precision floating-point format (sometimes called FP32 or float32) is a computer number format, usually occupying 32 bits in computer memory; it represents a wide dynamic range of numeric values by using a floating radix point.https://en.wikipedia.org › wiki › Single-precision_floating-poi...Single-precision floating-point format - Wikipedia number, a "float", stores a sign, a 24-bit binary numeral (the "significand"), and an eight-bit exponent by which to scale the numeral.


2 Answers

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.

like image 161
leftaroundabout Avatar answered Sep 19 '22 00:09

leftaroundabout


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.

like image 26
Willem Van Onsem Avatar answered Sep 21 '22 00:09

Willem Van Onsem