[Haskell-cafe] Default implementation of Floating (**)

Viktor Dukhovni ietf-dane at dukhovni.org
Wed May 19 15:13:30 UTC 2021


On Wed, May 19, 2021 at 11:50:22AM -0300, Fabrício Olivetti de França wrote:

> Investigating the source of this problem, I found that it uses the
> default implementation of (**) from base defined as x ** y = exp (log
> x * y).

The type of (**) is: Floating a => a -> a -> a
with the base and exponent having the same type.

The only practical way to define pow(x, y) for a floating point y, is
via the exp() and log() functions.

> So I was wondering, is there any reason to have this (potentially
> dangerous) default implementation on base?

The behaviour for negative inputs seems to be correct:

    λ> log(-2)
    NaN
    λ> exp(log(-2))
    NaN
    λ> exp(log(-2) * (-2))
    NaN
    λ> log(0)
    -Infinity

were you expecting these to check for non-positive inputs and to throw a
floating point exception?  When I compile and run:

    #include <math.h>
    #include <stdlib.h>
    #include <stdio.h>

    int main(int argc, char *argv[])
    {
        char *arg = argv[1] ? argv[1] : "1.0";
        double d = atof(arg);

        printf("log %s = %f\n", argv[1] ? arg, log(d));
        return 0;
    }

I get:

    $ ./log -2
    log -2 = nan
    $ ./log 0
    log 0 = -inf

so it rather looks like GHC's `log` returns whatever the underlying
floating point library returns...

-- 
    Viktor.


More information about the Haskell-Cafe mailing list