lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Note that NaN has multiple binary représentations, some of them designed as "signaling" and others non-signaling. The signaling bit uses only 1 bit in the mantissa, that must not be all ones, leaving more than 50 bits for other information, such as the cause of a NaN to be generated. These bits are used variable depending on hardware FPU or emulation librairies. Note as well that NaN incluses the sign bit as the most signifiant bit of the mantissa, but the signaling bit is just the next one. Then the next bit can be set to 0, to distinguish a non-signaling NaN from plus or minus Infinity.

In Java, all these NaN values are unified to a single value. Some libraries are also unifying the sign of zeroes, forcing it to be "positive". So finally there remains only two binary-encoded FP values that can have their exponent part set to its minimum value, à single zero and a single NaN treated as no' signaling. 

This is important to note if you serialize FP values in binary form, in order for example to generate digital signatures. Not all C librairies or compiler make effort to unify FP zeroes or NaNs. Some are also reducing possible "denormalized" numbers to zero, preserving their sign in the FP signed zero, or dropping it completely. 

So how extra bits in NaN (including the sign bit) or the extra sign bit of FP zero is usable or not remains platforms dépendant. For librairies that recognize these bits as signifiant, minus zero is distinct when compared for strict identity, but usually not for numeric comparators, eg used for sorting or matching keys in hashed tables. And a text representation of NaN may display à negative sign and an extension after "NAN", usually in parentheses and showing the extra bits usually as a decimal integer within these parentheses. Some librairies that have semantics for signaling NANs may also use an "!" character after the "NaN" constant but before the extension in parentheses

Le mar. 20 juin 2023 à 17:54, Lorenzo Donati <lorenzodonatibz@tiscali.it> a écrit :


On 20/06/2023 17:14, Hugo Musso Gualandi wrote:
>
>> On 20/06/2023 16:14, Hugo Musso Gualandi wrote:
>>> In Pallene we try from "%.6g" to "%.17g" and pick the smallest one
>>> that round-trips to the original number. (We can't use %a because our
>>> output is C, not Lua).
>>
>> Are you bound to C89? C99 has %a:
>>
>> https://en.cppreference.com/w/c/io/fprintf
>
> Currently we do try to support c89.  Also, we found that using decimal
> when possible was more readable :)
>
> By the way, beware that "%a" doesn't always produce something that's a
> valid C or Lua literal. For example, it might return "inf" or "-nan".

Yep, that's why I mentioned C99 and strtod. In C99 strtod can convert
"inf" and "nan" to actual float infinities and NaNs.

IDK if Lua uses strtod internally to implement "tonumber", but if it
does and it is compiled as C99 it should (could?) support also "nan" and
"inf".