[Cfp-interest] tgmath and narrowing functions

Jim Thomas jaswthomas at sbcglobal.net
Mon Nov 13 09:29:53 PST 2017


Joseph Myers has pointed out issues with the tgmath specification in Part 3 for functions that round to narrow type. His email messages are included here. While looking into these issues, I saw another problem, discussed below.

 

> Joseph Myers <joseph at codesourcery.com>
> 
> (SC22WG14.14879) Floating-point DR#13 and integer arguments to type-generic macros
> 
> To: SC22 WG14 sc22wg14 at open-std.org <mailto:sc22wg14 at open-std.org>
>  
> 
> The proposed resolution to floating-point DR#13 (regarding type-generic 
> macros for functions that round result to narrower type) includes 
> "Arguments that have integer type are regarded as having type _Decimal64 
> if any argument has decimal floating type, and as having type double 
> otherwise.".
> 
> This runs into problems if all the arguments to a macro such as d32add are 
> of integer type, because now they are being regarded as of type double, 
> whereas in TS 18661-2 it was clear that it was valid to pass integer 
> arguments to the d32add macro and it would result in d32addd64 being 
> called (and passing such arguments to the d64add macro would result in 
> d64addd128 being called).  Is that intended - that these macros should not 
> be valid with only integer type arguments?  Or should the logic for what 
> type integer arguments are considered to have be based on the macro prefix 
> in this case?
> 
 The latter: the logic for what type integer arguments are considered to have should be based on the macro prefix 

> That DR resolution also appears to leave results not fully determined in 
> the case of integer arguments.  The chosen function is specified by "The 
> unsuffixed name of the function is the name of the macro, and its suffix, 
> if any, corresponds to the parameter type which may be any type with at 
> least the range and precision of the argument types.", but whereas for 
> floating-point arguments the result of the call does not depend on exactly 
> which function gets called, as long as the parameter type has enough range 
> and precision, for integer arguments it *does* matter whether (for 
> example) a call of f32add with two long long arguments ends up calling 
> f32addf64 or f32addf128, because loss of precision when converting such 
> arguments to _Float64.
> 
> Possibilities for the not-fully-determined result include: allow it being 
> not fully determined (and maybe add this case to the list in part 5 of the 
> TS of features that prevent reproducibility); require the integer 
> arguments to be converted to the type they are considered to have; put in 
> some rules that determine the type more precisely in the case of integer 
> arguments; apply the "any type with at least the range and precision of 
> the argument types" to the original integer types rather than to 
> _Decimal64 / double (which would imply that e.g. calling fadd / dadd with 
> long long arguments is not valid if long double is IEEE binary64, because 
> then long double wouldn't be able to represent all long long values).  
> (Even if the type can represent all values of the integer argument type, 
> you still have issues of decimal exponents depending on what the chosen 
> type is, but that may be less significant.)
> 
> -- 
> Joseph S. Myers
> joseph at codesourcery.com <mailto:joseph at codesourcery.com>
>  
> 
> Joseph Myers <joseph at codesourcery.com>
> 
> (SC22WG14.14880) Floating-point DR#13 and integer arguments to type-generic macros
> 
> To: SC22 WG14 sc22wg14 at open-std.org <mailto:sc22wg14 at open-std.org>
>  
> 
> On Mon, 6 Nov 2017, Joseph Myers wrote:
> 
> 
> 
> TS of features that prevent reproducibility); require the integer 
> arguments to be converted to the type they are considered to have; put in 
> 
> 
> (Or to the common type of the arguments determined as in DR#9, to make 
> these macros as similar as possible to the other type-generic macros, so 
> that the case of (long long, long long) arguments would convert them to 
> double, or maybe to _Decimal64 for a decimal type-generic macro, but (long 
> long, long double) would convert the long long argument to long double.)
> 
Yes, I think this is the right approach.

> -- 
> Joseph S. Myers
> joseph at codesourcery.com <mailto:joseph at codesourcery.com> 

There’s another problem here. We say that the function prefix is the same as the macro prefix and we determine the type for generic parameters from the argument types. It may happen that the prefix is for a standard floating type and the parameter type is an interchange or extended floating type, or vice versa. In these cases there is no such function. An simple example is the macro invocation fadd(x, y) where x and y are _Float64.

 Options for addressing this problem include the following.


 1. We could simply say that such cases result in undefined behavior. In the example above, the user could invoke fadd((double)x, (double)y) or (float)f32add(x, y), but not fadd(x, y). I don’t see a portable way to get the effect of such as fadd(x, y) if x is _Decimal32x and y is long double, where the determined parameter type group will differ among implementations.


 2. We could add functions to cover all these cases. Thus something like


 faddfN for N > 32


faddfNx for N >= 32

daddfN for N > 64

daddfNx for N >= 64

going this far seems to call for laddfN and laddfNx

f16addf

fNadd for N < 64

f32xadd

fNaddl for all N???

fNxaddl for all N???

3. I tried to devise a scheme where float and double are regarded as _Float32 and _Float64 to avoid type group mismatches, but it got complicated and long double was still a problem. More effort could be applied here if neither option 1 or 2 is acceptable.


 

What do you think? We’ll discuss this at the CFP teleconference tomorrow.



Jim
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20171113/aaaa8ed0/attachment-0001.html 


More information about the Cfp-interest mailing list