javahaskellcastingfloorfrege

Frege Double to Integer


I would like to be able to convert a large Double to an Integer, but it seems that the Frege Haskell implementation of floor does not yield an Integral type. Instead, it seems to be implemented to interface with way Java does it, and takes a Floating type to a Double, Floating r => r -> Double. I could use round, but that rounds rather than truncate (though I might be able to subtract 0.5 and then round). I'd rather work without needing to resort to using Int or Long, which, as wide as the latter is, is still limited in precision.

Any way to go about flooring a floating point type to an arbitrary precision integer type?


Solution

  • This functionality is indeed not available. The reason is that Java apparently doesn't offer methods that support it.

    What you can do is to convert the (floored) double to a String and converting that to an Integer.

    Here is an example:

    frege> import Prelude.Math(floor)
    frege> integerFromDouble d = String.aton ("%.0f".format (floor d))
    function integerFromDouble :: Math.Floating a => a -> Integer
    frege> integerFromDouble 987654321e20
    98765432100000000000000000000
    

    I wonder if there is a more effective method that somehow extracts the mantissa and exponent from a Double and computes the Integer.

    Note that above function is unsafe because NaN, +Infinity and -Infinity exist:

    frege> integerFromDouble (5/0)
    java.lang.NumberFormatException: For input string: "Infinity"
    

    You could either check that separately or replace String.aton with String.integer , which returns

    Either NumberFormatException Integer
    

    If you can make sure your computations don't exceed the Long capacity, what you want can be done with:

    round . floor