• Brian Kessler's avatar
    math: eliminate overflow in Pow(x,y) for large y · 12465661
    Brian Kessler authored
    The current implementation uses a shift and add
    loop to compute the product of x's exponent xe and
    the integer part of y (yi) for yi up to 1<<63.
    Since xe is an 11-bit exponent, this product can be
    up to 74-bits and overflow both 32 and 64-bit int.
    
    This change checks whether the accumulated exponent
    will fit in the 11-bit float exponent of the output
    and breaks out of the loop early if overflow is detected.
    
    The current handling of yi >= 1<<63 uses Exp(y * Log(x))
    which incorrectly returns Nan for x<0.  In addition,
    for y this large, Exp(y * Log(x)) can be enumerated
    to only overflow except when x == -1 since the
    boundary cases computed exactly:
    
    Pow(NextAfter(1.0, Inf(1)), 1<<63)  == 2.72332... * 10^889
    Pow(NextAfter(1.0, Inf(-1)), 1<<63) == 1.91624... * 10^-445
    
    exceed the range of float64. So, the call can be
    replaced with a simple case statement analgous to
    y == Inf that correctly handles x < 0 as well.
    
    Fixes #7394
    
    Change-Id: I6f50dc951f3693697f9669697599860604323102
    Reviewed-on: https://go-review.googlesource.com/48290Reviewed-by: 's avatarRobert Griesemer <gri@golang.org>
    12465661
pow.go 3.22 KB