[Cfp-interest 1698] Re: printf with %a

Paul Zimmermann Paul.Zimmermann at inria.fr
Sat Jul 18 23:25:10 PDT 2020


       Dear Jim,

I understand your reasoning. I would say there is something underspecified
in the C standard. For me, it should not be allowed to have two results
with different values (0x2p+1 and 0x3p+0) for the same operation, which is
the spirit of IEEE 754.

Best regards,
Paul

> From: Jim Thomas <jaswthomas at sbcglobal.net>
> Date: Sat, 18 Jul 2020 10:57:51 -0700
> 
> > On Jul 17, 2020, at 9:53 PM, Paul Zimmermann <Paul.Zimmermann at inria.fr> wrote:
> > 
> >>> On Jul 17, 2020, at 8:57 AM, Fred J. Tydeman <tydeman at tybor.com> wrote:
> >>> 
> >>> Is
> >>> printf("%-+#.0La", 3.0L);
> >>> allowed to output  "+0x2.p+1"
> >>> instead of "+0x3.p+1"
> >>> for IEEE-754 binary floating-point?
> > 
> > with gcc 9.3.0 I get +0xc.p-2. Source file is:
> > 
> > #include <stdio.h>
> > int main()
> > {
> >  printf("%-+#.0La\n", 3.0L);
> > }
> > 
> > I would say indeed it should be corrected rounded according to C 7.21.6.1#11,
> > thus you cannot get +0x2.p+1.
> 
> I hope this is true.  Some thoughts about it …
> 
> Just looking at C, +0x2.p+1 seems to be allowed. C 7.21.6.1 says, for a,A formatting, 
> 
> "… there is one hexadecimal digit (which is nonzero if the argument is a normalized floating-point number and is otherwise unspecified) before the decimal-point character …"
> 
> This requirement is satisfied by +0x2.p+1 and it is arguably correctly rounded, assuming default rounding direction. 
> 
> However, IEEE 754 5.12.2 (regarding conversions between floating-point formats and character sequences) says
> 
> "Within the limits stated in this clause, conversions in both directions shall preserve the value of a number unless rounding is necessary …"
> 
> In this case rounding is not necessary, in the sense that an allowable result could be written without rounding. Since Annex F assumes IEEE 754 by reference, we could say that +0x2.p+1 is not allowed if the implementation supports Annex F.
> 
> On the other hand, …. The flexibility in C for different 1s digits in the hex output is explained in the footnote:
> 
> "295)Binary implementations can choose the hexadecimal digit to the left of the decimal-point character so that subsequent digits align to nibble (4-bit) boundaries."
> 
> Following this suggestion, an implementation might reasonably choose for type double to always print “1” as the 1s digit (for normal values) so that hex digits to the right of the decimal-point character look like a hex representation of memory. With this approach, the 0 formatting precision means the value 3 is to be rounded to 1 bit precision. The result would be +0x1.p+2 with an inexact exception. Interestingly, this case seems to covered by some new text in IEEE 754-2019 (after the ‘;’):
> 
> "if the two nearest floating-point numbers bracketing an unrepresentable infinitely precise result are equally near, the one with an even least significant digit shall be delivered; if that is not possible, the one larger in magnitude shall be delivered (this can happen for one-digit precision, possible with convertToDecimalCharacter …"
> 
> The awkwardness comes from the fact that the hex digit base (16) is different from the exponent base (2).
> 
> I'll add this to the agenda for next week’s CFP meeting.
> 
> - Jim Thomas
> 
> 
> > 
> > 
> 
> > Paul Zimmermann


More information about the Cfp-interest mailing list