On Wed, 29 Apr 2026 08:34:37 GMT, Anton Artemov <[email protected]> wrote:

> Hi, please consider the following changes:
> 
> This is a fix for the `StrictMath.pow()` method, which corrects its numerical 
> behavior in certain cases. 
> 
> It was recently reported by [Gladman et 
> al](https://members.loria.fr/PZimmermann/papers/accuracy.pdf) that the 
> `pow()` method in the original FDLIBM returns with error of 636 ulps in 
> certain cases. `StrictMath.pow()` is a direct port of FDLIBM `pow()`.
> 
> It turned out that `ivln2` constant split into high  and low parts (`ivln2_h` 
> and `ivln2_l` respectively) in the original method is not sufficient to 
> compute `u = ivln2_h * t` exactly in certain cases, namely when the span of 
> non-zero bits in `t` is wide. 
> 
> By the default split, the high part `ivln2_h` contains 24 high bits of 
> `ivln2`, and by changing the split so that `ivln2_h` contains only 21 bits of 
> `ivln2` we ensure that `u = ivln2_h * t` is computed exactly in all cases 
> when pow(x,y) does no overflow.
> 
> New testcases added.
> 
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK 
> Interim AI Policy](https://openjdk.org/legal/ai).

I confirm this fixes the issue. With the following patch to openlibm 0.8.7 (I 
don't have easy access to openjdk with my tools, and I didn't update the 
comment):

$ diff e_pow.c.orig e_pow.c
95,96c95,96
< ivln2_h  =  1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
< ivln2_l  =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 
tail*/
---
> ivln2_h  =  1.4426946640014648438, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
> ivln2_l  =  3.7688749856360991145e-07; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/

the maximal error I find reduces to less than 1 ulp:
``` 
Checking pow with openlibm-0.8.7-patched
pow 0 -1 0x1.a26d96e778dc8p+163,0x1.90d5de9f964f6p-9 [0.895] 0.894019 
0.8940184425798512

This matches the maximal error found by Newlib 4.6.0 (our comparison says 0.892 
but it is indeed 0.895). I guess a similar patch was applied to Newlib between 
4.50 (which has a maximal error of 169 ulps) and 4.6.0.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/30984#issuecomment-4478035820

Reply via email to