[Haskell-cafe] about integer and float operations

Manlio Perillo manlio_perillo at libero.it
Wed Feb 4 16:09:30 EST 2009


Yitzchak Gale ha scritto:
> Manlio Perillo wrote:
> [...]
>> The second difference is about the division of two integers.
>>>>> fac(777) / fac(777)
>> 1.0
>> Here CPython does not convert the two integers to float before to divide
>> them, but make use of a special algorithm.
>> GHC, instead, returns NaN
> 
> No, actually here Haskell shines. Perhaps this GHCi session
> will illuminate the issue for you:
> 
> Prelude> let fac n = product [2..n]
> Prelude> fac 777 `div` fac 777
> 1
> Prelude> fac 777 / fac 777
> NaN
> 

No, this is not as complete as it is done in Python.

In recent versions of Python you have two division operators.
The `/` operator *always* perform a true division.
As an example, the division of two integers return a float.

The `//` operator *always* perform a "floor" division.
This happens for both integers and floats:

 >>> 2.5 // 1.5
1.0
 >>> 2.5 / 1.5
1.6666666666666667

In Haskell:
Prelude> 2.5 `div` 1.5

<interactive>:1:0:
     Ambiguous type variable `t' in the constraints:
       `Integral t' arising from a use of `div' at <interactive>:1:0-12
       `Fractional t'
         arising from the literal `1.5' at <interactive>:1:10-12
     Probable fix: add a type signature that fixes these type variable(s)

(but this seems to be available with Data.Fixed, however on Debian Etch 
I still have GHC 6.8.2).


As for your example:

 > Prelude> let fac n = product [2..n]
 > Prelude> fac 777 `div` (4 * fac 776)
 > 194

This is incorrect, because `div` returns an integer, but I want a float 
with the exact result (194.25 with Python).

If I'm correct, there is no operator/function, in Haskell, that perform 
an exact division between two integers and return a float:

exactDiv :: (Integral a, Real b) => a -> a -> b



I personally prefer the Python solution, where we have two operators 
with the same behaviour over all the numbers.

In Haskell, something like

(/) :: (Num a, Real b) => a -> a -> b
(//) :: (Num a, Integral b) => a -> a -> b


 > [...]



Thanks  Manlio Perillo


More information about the Haskell-Cafe mailing list