ISO/ IEC JTC1/SC22/WG14 N1094


N1094

Three possible Defect Reports from Fred Tydeman.

1) %.0a and rounding

Given FLT_RADIX is 2 and that
  printf("%.1a", 3.0);
has these four possible outputs
  0xc.0p-2
  0x6.0p-1
  0x3.0p+0
  0x1.8p+1

Are the possible outputs of
  printf("%.0a", 3.0);
these:
  0xcp-2
  0x6p-1
  0x3p+0
  0x2p+1  -- round up
  0x1p+2  -- round up
  0x1p+1  -- round down

In particular, are the three cases that round and drop bits allowed,
where there are alternate representations that do not lose any data?

This case of dropping bits has come up in real implementations.  Some
always use less than 4 bits in the first hex digit output, while
others do that only if there is no rounding error.

C99+TC1 has:

3.9 correctly rounded result
7.19.6.1 The fprintf function
 para 8 a,A along with footnote 236
 para 11
 para 12

I contend that correctly rounded requires the use of a representation
that minimizes the error between what is output and the value being
output.

I believe footnote 236 should be changed to:

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, as long as this representation has no more
rounding error than if the first hexadecimal digit were 8 or greater.


2) %a and trailing zeros

Given that FLT_RADIX is 2 and x is a double, what is the output of:
  printf("%a", x);

Some choices that occur to me are:

  1) use the smallest precision for an exact representation of this
  particular value; in effect, remove trailing zeros.

  2) use the smallest precision for an exact representation of all
  values of this type; in effect, keep trailing zeros.

  3) use the smallest precision for an exact representation of all
  values of all floating-point types; in effect, promote to long
  double and keep trailing zeros.

  4) implementation defined.

  5) unspecified.

  6) something else.

Some implementations that I have seen do 1, others do 2, and one does
both 1 and 2 (value and format dependent).  I believe choice 1 is the
intended behaviour.

7.19.6.1 The fprintf function, 

Paragraph 6 on the '#' flag has: "For g and G conversions, trailing
zeros are not removed from the result."

Paragraph 8, section a,A, has: "if the precision is missing and
FLT_RADIX is a power of 2, then the precision is sufficient for an
exact representation of the value;"


3) freopen

Given these:
  #include <stdio.h>
  static char *filename = NULL;
  static FILE *file = NULL;
  filename = tmpnam(NULL);
  file = fopen(filename,"wb");

Are these two equivalent:
   file = freopen(filename, "wb", file);
   file = freopen(    NULL, "wb", file);

That is, do both succeed, or both fail for the same reason?

Some implementations succeed with the explicit filename, but fail with
the implicit filename; while others succeed for both.  I believe that
these two are equivalent by the "as if" in 7.19.5.4.

7.19.5.4 The freopen function, paragraph 3 has: If filename is a null
pointer, the freopen function attempts to change the mode of the
stream to that specified by mode, as if the name of the file currently
associated with the stream had been used. It is implementation-defined
which changes of mode are permitted (if any), and under what
circumstances.

Does the "implementation-defined" apply to just the NULL case, or does
it apply to both cases (in which case, should it be its own
paragraph)?