Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20261029232855.GS3542221@port70.net>
Date: Fri, 30 Oct 2026 00:28:55 +0100
From: Szabolcs Nagy <nsz@...t70.net>
To: Bernie Innocenti <bernie@...ewiz.org>
Cc: musl@...ts.openwall.com
Subject: Re: [PATCH] math: fix fma(x,y,0) double rounding with excess
 precision

* Bernie Innocenti <bernie@...ewiz.org> [2026-10-30 06:57:38 +0900]:
> with FLT_EVAL_METHOD==2 (i386 x87, m68k with 68881) x*y is rounded
> to long double first and then to double, e.g.
> 
>   fma(0x1.27365a6456ba5p+0, 0x1.63fdaf7759a4fp+0, 0.0)
> 
> returned 0x1.9a84ea6842dccp+0 instead of 0x1.9a84ea6842dcdp+0.
> 
> add the zero z exactly on the integer path instead: then x*y is
> rounded once in the current rounding mode with its own sign, which
> keeps the fix of commit 9683bd62414604d3bd56cf6bd7be8f54aa31e7d3.
> 
> found by arczi84 (GitHub) reviewing a port of this code to newlib.
> ---
>  src/math/fma.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/src/math/fma.c b/src/math/fma.c
> index adfadca8..072e8e5d 100644
> --- a/src/math/fma.c
> +++ b/src/math/fma.c
> @@ -52,9 +52,13 @@ double fma(double x, double y, double z)
>  	if (nx.e >= ZEROINFNAN || ny.e >= ZEROINFNAN)
>  		return x*y + z;
>  	if (nz.e >= ZEROINFNAN) {
> -		if (nz.e > ZEROINFNAN) /* z==0 */
> -			return x*y;
> -		return z;
> +		if (nz.e == ZEROINFNAN)
> +			return z;
> +		/* z==0: x*y would round twice with FLT_EVAL_METHOD==2,
> +		   so add z exactly, x*y then rounds once with its own sign */
> +		nz.m = 0;
> +		nz.e = nx.e + ny.e;
> +		nz.sign = nx.sign ^ ny.sign;

this looks good
thanks.

>  	}
>  
>  	/* mul: r = x*y */
> -- 
> 2.56.0

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.