[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: output rounding bug in vasnprintf %e format implementation
From: |
Bruno Haible |
Subject: |
Re: output rounding bug in vasnprintf %e format implementation |
Date: |
Sat, 19 Apr 2008 17:54:50 +0200 |
User-agent: |
KMail/1.5.4 |
Ben Pfaff wrote:
> By adding a printf
> around here, I can see that floorlog10 chooses an exponent of 3.
The floorlog10 function was intended to return a result with at most 10^-7
error. There was a bug here too (I confused log and log2.) This fixes it.
2008-04-19 Bruno Haible <address@hidden>
* lib/vasnprintf.c (floorlog10l, floorlog10): Reduce maximum error
from 0.0058 to less than 10^-7.
*** lib/vasnprintf.c.orig 2008-04-19 17:51:44.000000000 +0200
--- lib/vasnprintf.c 2008-04-19 17:45:19.000000000 +0200
***************
*** 1301,1309 ****
}
/* Now 0.95 <= z <= 1.01. */
z = 1 - z;
! /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
Four terms are enough to get an approximation with error < 10^-7. */
! l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
/* Finally multiply with log(2)/log(10), yields an approximation for
log10(x). */
l *= 0.30102999566398119523;
--- 1301,1309 ----
}
/* Now 0.95 <= z <= 1.01. */
z = 1 - z;
! /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
Four terms are enough to get an approximation with error < 10^-7. */
! l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z *
0.25)));
/* Finally multiply with log(2)/log(10), yields an approximation for
log10(x). */
l *= 0.30102999566398119523;
***************
*** 1392,1400 ****
}
/* Now 0.95 <= z <= 1.01. */
z = 1 - z;
! /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
Four terms are enough to get an approximation with error < 10^-7. */
! l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
/* Finally multiply with log(2)/log(10), yields an approximation for
log10(x). */
l *= 0.30102999566398119523;
--- 1392,1400 ----
}
/* Now 0.95 <= z <= 1.01. */
z = 1 - z;
! /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
Four terms are enough to get an approximation with error < 10^-7. */
! l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z *
0.25)));
/* Finally multiply with log(2)/log(10), yields an approximation for
log10(x). */
l *= 0.30102999566398119523;