[Cfp-interest 1669] Re: intmax_t removal

Jim Thomas jaswthomas at sbcglobal.net
Thu Jun 25 17:02:29 PDT 2020


Here’s a cut at a Description for fromfp and ufromfp functions with floating return types

double fromfp(double x, int round, unsigned int width);
double ufromfp(double x, int round, unsigned int width);
...

In 7.12.9.10 replace the Description with:

2 The fromfp and ufromfp functions round x, using the math rounding direction indicated by round, to a signed or unsigned integer, respectively. If width is nonzero and the resulting integer is within the range

[-2^(width-1), 2^(width-1) - 1], for signed
[0, 2^width - 1], for unsigned

the functions return the integer value (represented in floating type). Otherwise, if width is zero or x does not round to an integer within the range, the functions return an unspecified value outside the range and a domain error occurs. If the value of the round argument is not equal to the value of a math rounding direction macro (7.12), the direction of rounding is unspecified. The fromfp and ufromfp functions do not raise the "inexact" floating-point exception. 


Also, in F.10.6.10:

Change:

1 The fromfp and ufromfp functions raise the "invalid" floating-point exception and return an unspecified value if the floating-point argument x is infinite or NaN or rounds to an integral value that is outside the range of any supported integer type of the specified width. 

to:

1 The fromfp and ufromfp functions return a NaN and raise the "invalid" floating-point exception if the argument width is zero or if the floating-point argument x is infinite or NaN or rounds to an integer value that is outside the range determined by the argument width (see 7.12.9.2).


- Jim Thomas

> On Jun 25, 2020, at 10:12 AM, Jim Thomas <jaswthomas at sbcglobal.net> wrote:
> 
> 
> 
>> On Jun 24, 2020, at 4:35 PM, Fred J. Tydeman <tydeman at tybor.com <mailto:tydeman at tybor.com>> wrote:
>> 
>> On Wed, 24 Jun 2020 11:50:55 -0700 Jim Thomas wrote:
>>> 
>>> For the Summary, I suggest saying more about why we're recommending a change. The WG14 consideration of removing [u]intmax_t, sparked the CFP discussion. I think we concluded that changing the interfaces to not use [u]intmax_t would be better anyway (even if [u]intmax_t were not removed). Introducing type [u]intmax_t into an expression via a function return type could have unpredictable negative performance implications.
>> 
>> OK
>> 
>>> For the compoundn, pown, and rootn functions, long long int appears to be more than adequate for applications.
>> 
>> Not so sure about that.
>> Consider both: compoundn( DBL_MIN, 1.0/DBL_MIN ) and compoundn( 1.0/DBL_MAX, DBL_MAX )
>> They should have the value 2.718281828...
>> They need the 'n' argument to be the same type as the 'x' argument for that to work.
>> 
>> Also, consider pownl( 1.L+LDBL_EPSILON, 1.L/LDBL_EPSILON )
>> Again, it should have the value 2.718281828...
>> If long double is the 128-bit IEEE-754 format, then one needs a 113-bit integer
>> to hold the value 1.L/LDBL_EPSILON.  long long int is only required to hold 64 bits.
> 
> Why not use pow or powr for these calculations? Maybe David or Mike can say more about what 754 intended for compoundn, pown, and rootn.
> 
> These functions are in TS 18661-4 and have been implemented with integer type second parameters. We should have a very good reason for changing them.
> 
>> 
>>> The changes to compoundn, pown, and rootn seem straightforward.
>> 
>> I prefer changing them to make both parameters be the same floating-point type
>> along with adding:  If 'n' is not an integer (in floating-point format), then the results are
>> undefined (or unspecified).
> 
> We’ve generally tried to avoid that sort of undefined or unspecified behavior.
>> 
>>> On further thought, the change to the fromfp functions does not. For example, what
>>> would the functions do if the input does not round to an integer of the given width?
>> 
>> They already have text (in N2478) for that error case:
>>  result is unspecified and a domain error happens.
>> I am not changing that.
> 
> The text you’re referring to is "If x is infinite or NaN or rounds to an integral value that is outside the range of any supported integer type of the specified width, or if width is zero, the functions return an unspecified value and a domain error occurs.”
> 
> “or rounds to an integral value that is outside the range of any supported integer type of the specified width” seems wrong (at best ambiguous). Is -2 outside the range of any integer type of width 32? What if there is no supported type of the specified width? Better might be something like “… or rounds to an integral value that is outside the range of integers (signed or unsigned, respectively) of the specified width, …”.
> 
> 
> If we change the return type to floating, we can do better than return an unspecified value. I’ll send suggestions in a subsequent message.
> 
>> 
>>> The key point for IEC 60559 binding is that composing the function with a cast (or assignment) of the result to the desired integer type must have the behavior of the corresponding IEC 60559 conversion from floating-point to integer operation. For example, to convert from double to int128_t using to-nearest rounding without inexact, do
>>> 
>>> double d;
>>> int128_t i128;
>>> i128 = fromfp(d, FE_INT_UPWARD, INT128_WIDTH);
>>> 
>>> In the process of rewriting the Description for the fromfp functions, I wondered ...
>>> 
>>> Do we already have this functionality (without the fromfp functions)? For example, could the conversion above be done with
>>> 
>>> double d;
>>> int128_t i128;
>>> {
>>> #pragma STDC FENV_ROUND FE_UPWARD
>>> i128 =nearbyint(d); // or rint to raise inexact
>>> }
>>> 
>>> The nearbyint rounds to integer value using the given rounding direction, and preserves infinities and NaNs.
>> 
>> OK.  But, I think it will be a long time before compilers support that pragma.
> 
> It could also be done by changing the dynamic rounding direction mode. The pragma would seem to be an advantage for any HW that can encode the rounding direction in instructions.
>> 
>>> The assignment to i128 will raise invalid if the function result is infinite, NaN, or out of range.
>> 
>> That is what is supposed to happen.  However, in my testing of compilers for 26 years,
>> I have only encountered one compiler that did that (and only for a few releases; later
>> releases did not do that).  There are no current compilers that I have access to that
>> raise invalid for all cases of out of range results.  So, I am hoping that having these
>> functions will get the correct behaviour for all cases.
> 
> Hmm. This might be a discussion topic for the next CFP meeting. 
> 
> - Jim Thomas
>> 
>> 
>>> Does this handle all the edge cases (infinities, NaNs, our of range values, exceptions) per IEC 60559? Does the scheme work for the combinations of floating and (signed and unsigned) integer types? If so, would this be an acceptable binding?
>> 
>> 
>> I believe it works in theory, but current compilers are not doing it in practice.
>> 
>> 
>> 
>> ---
>> Fred J. Tydeman        Tydeman Consulting
>> tydeman at tybor.com <mailto:tydeman at tybor.com>      Testing, numerics, programming
>> +1 (702) 608-6093      Vice-chair of PL22.11 (ANSI "C")
>> Sample C99+FPCE tests: http://www.tybor.com <http://www.tybor.com/>
>> Savers sleep well, investors eat well, spenders work forever.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20200625/a4ae0b2c/attachment-0001.htm>


More information about the Cfp-interest mailing list