Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260818191035.GH3542221@port70.net>
Date: Tue, 18 Aug 2026 21:10:35 +0200
From: Szabolcs Nagy <nsz@...t70.net>
To: musl@...ts.openwall.com, Sergey Davidoff <shnatsel@...il.com>
Subject: Re: [PATCH v3] math: fmaf fixes

* Szabolcs Nagy <nsz@...t70.net> [2026-08-17 02:22:33 +0200]:
> the new code uses that for all real |x| in [0x1p-999,0x1p999]
> 
>   y = (float)x
> 
> is the same as
> 
>   r = (double)x
>   t = x - r
>   if (t!=0 && (r.bits&0xfffffff)==0)
>     r.bits += (r<0)==(t<0) ? 1 : -1
>   y = (float)r
> 
> in all rounding modes, with the same fenv effects. note: using
> r.bits&1 this can be interpreted as a round to odd adjustment,
...
> +	if ((u.i & 0xfffffff) == 0 && e < 0x3ff+128) {
> +		/* correct except for inf, nan and some (r&1)==1 cases.
> +		 * r+t == x*y+z exactly in nearest rounding mode and in
> +		 * other modes the t!=0 and t<0 checks are not affected.
> +		 * if t==0 then inexact is not signaled. */
> +		int s = u.i >> 63;
> +		double t = s == (xy < z) ? xy - u.r + z : z - u.r + xy;
> +		if (t)
> +			/* adjust r toward r+t */
> +			u.i += s == (t < 0) ? 1 : -1;
> +	}

round to odd (with sr,st in 0,1):

  if (u%2 == 0)
    u += sr == st ? 1 : -1;

can be written as

  u -= sr ^ st;
  u |= 1;

compilers don't seem to do this transformation, but then
u&0xfffffff can be removed without making the adjust more
expensive. this saves some bytes and may only regress
subnormal range cases a bit. maybe a better tradeoff.

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.