Doc. No.: WG14/N1197
Date:     2006-10-17
Project:  Programming Language C (TR 24732)
Subject:  Comments to N1176
 

1) Function return value

The return value from function should be treated like simple assignment. This means implicit conversion is done (DFP vs other data type) when the return expression type doesn't match the prototype.
 

2) xxx_DEN macros

IEEE 754R has deprecated the term "denorm" in favour of "subnormal", we should use (for example) "xxx_SUBNORM" instead of xxx_DEN. (5.2.4.2.2a)
 

3) Mixed operations between DFP and generic floating types

N1176 section 6.4, "Usual Arith. Conversions" doesn't allow implicit conversion between DFP <--> BFP. Should we treat this as a constraint violation ?
 

4) Mixed operations between dfp types and integer type

N1176 section 6.4, "Usual Arithmetic Conversions", says "If one operand is a decimal floating type, all other operands shall not be generic floating type, complex type, or imaginary type". The intention is to allow mixed operations between DFP types and integer types. However, in section 8 "Arithmetic Operations" for each of the operators it says "If either operand has decimal floating type, the other operand shall have decimal floating type."
The text in section 8 is not correct. Suggest to change it to:

"... the other operand shall not have generic floating type, complex type, or imaginary type"
 

5) Conversions between DFP and integer types

N1176, 6.1, suggested change for 6.3.1.4. When converting a DFP type to an integer type, if the resulting value cannot be represented, an "invalid" exception is raised. This is different from the corresponding behavior for generic floating type, which gives undefined behavior. We should keep them the same and change DFP's behavior to undefined.

5a)
This leads to another comment: For generic floating types, Annex F specifies more stringent behaviors following IEEE 754. Should we take the same approach for DFP types -- that is, follow the generic types behaviors in the mandatory part so that the floating types are consistent, and then use an Annex to capture the behaviors according to 754R.

5b)
There are other changes in 754R (with respect to 754) which affects all floating types, not just behaviors for DFP. What is the best way to handle these changes ?
 

6) Precision of Formatted Output specifiers

The precision of the formatted input/output specifiers when they are not given is defaulted to 6. This follows the current specification for generic floating type. However, the precision of the DFP is encoded in the representation, so we can use this when the precision is not given.

Add the following to 7.19.6.1 paragraph 7, to 7.19.6.2 paragraph 11, to 7.24.2.1 paragraph 7, and to 7.24.2.2 paragraph 11:

H Specifies that a following e, E, f, F, g, or G conversion specifier applies to a _Decimal32 argument.

D Specifies that a following e, E, f, F, g, or G conversion specifier applies to a _Decimal64 argument.

DD Specifies that a following e, E, f, F, g, or G conversion specifier applies to a _Decimal128 argument.

Change the text beginning:

A double argument representing …

in the descriptions for the e, E, f, F, g, and G conversion specifiers in 7.19.6.1 paragraph 8 and 7.24.2.1 paragraph 8 to:

f, F A double or decimal floating type argument representing a floating-point number is converted to decimal notation in the style [-]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is determined from the argument if the length modifier is H, D or DD, otherwise it is taken as 6 [273a]; ...

e,E A double or decimal floating type argument representing a floating-point number is converted in the style [-]d.ddd e+-dd, where there is one digit (which is nonzero if the argument is nonzero) before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is determined from the argument if the length modifier is H, D or DD, otherwise it is taken as 6 [273a]; ...

g,G A double or decimal floating type argument representing a floating-point number is converted in style f or e (or in style F or E in the case of a G conversion specifier), depending on the value converted and the precision. Let P equal the precision if nonzero, the precision of the argument if the precision is omitted and the length modifier is H, D or DD [273a], 6 if the precision is omitted and the length modifier is not H, D and DD, …
 

273a] IEEE 754R defines decimal floating point encodings that encode both the value and precision.
 


7) Internal representation of TTDT

It is unnecessary to give a “recommended practice” for the type of TTDT. We should leave this up to the implementation to decide. Since this is used during compile time, and performance on processing floating-point literal is not an issue, an implementation may choose to use arbitrary precision arithmetic for compile time constants. Other clever and efficient methods probably exist as well to represent TTDT so that if the final type is a binary floating-point type, the resulting value would be exactly the same as one would get from the current C99 specification.

The current proposal in N1176 (section 7.1.1, the suggested change to 6.4.4.2, the “recommended practice”), is to use _Decimal128. Suggest to remove it.

 

Comment from HP for their vote to abstain:

 

I. Document structure

This draft is structured as a set of edits to the main body of C standard.  Given the huge amount of implementation and testing effort implied by these features, the absence of demonstrated commercial prior art, and the relatively slow adoption of the full Annex F features in the marketplace, HP feels that it would be more prudent to structure the TR as an “optionally-normative" Annex, more along the lines of the existing Annex F.

 

II. Design rationale

The rationale document (but not the TR) addresses the issue of choosing to add three new types rather than specifying the behavior of mapping the three existing standard floating-point types onto the IEEE decimal radix types.  The rationale document's arguments are very thin, and most of them controvert industry experience with using a translation-time option (not a pragma) to map the standard types either onto an IEEE representation or onto the vendor's proprietary representation.  The impact of this choice on the extent of change in the language and also in the implementation, is enormous. It would be helpful if the rationale could more clearly demonstrate the importance of being able to use the decimal-radix types "on equal footing" with the default types *within the same translation unit*.

 

III. Detailed comments on the text by section:

2.1:  It should be clearly stated that the TR defers to 754R if there are any inconsistencies.  If this is not the case, then areas of discrepancy should be clearly identified.

3:  Seems like conformance macros for TRs should start with something other than __STDC__.  The TRs aren't part of standard C and if and when one is integrated into the standard it may change somewhat.

6.1 [1a] sentence 3:  If the value of the integer part is less than zero, then for conversion to unsigned I think it's better to return the most positive value instead of 0, because it is a more noticeable and likely indication that an invalid operation may have occurred.

6.1 [2a]:  Note that conversion from integer to a standard decimal FP type can overflow only if the integer type is enormous (over 300 bits), because _Decimal32 values go up to 9.999999e96.

6.1 [2a], near:  There is no overflow in the case described in the first clause, but the draft suggests otherwise.

6.1 [2a], negative infinity:  Text is incorrect.  One fix is to change "near" to "zero", the first "negative" to "positive".

6.1 [2a], near:  The text should acknowledge that there are two flavors of round to nearest.  The effect of overflow happens to be the same for both of them.

6.2:  See problems with 6.1 above.

7:  Why have d and D suffixes for binary been added in this TR (about decimal)?  Needs rationale.

7.1:  The use of TTDT seeks a modest user convenience in not having to suffix decimal constants.  However, it undermines the predictability for FP calculation that Annex F and the floating-point standard have established.  With the TTDT scheme, the value of FP constant expressions could vary from one implementation to the next depending on implementation-defined TTDTs.  Translation and execution-time results could differ.  It's a fact that floating constants with 36 significant digits can distinguish general binary FP values with the width of binary128 or less;  however, if TTDT were decimal128, then two digits would be lost from floating constants expressed with 36 significant digits, which could have the effect of determining a different double value.  The cost is way too high for the convenience.

9.2:  Decimal arithmetic may need its own exception flags.  I don't believe this issue is quite settled yet in 754R.

9.3:  A lot of decimal functions!

9.5-9.6:  These sections must deal with the fact that a numerical value typically has multiple representations in a decimal type, and the differences matter.  Conversion between decimal types and character sequences need to be specified so that:

a) it's clear how particular internal representations are determined from character sequence input

b) it's clear how the user can format character sequence output so that converting from decimal types to character sequences and back preserves the representations. See http://www2.hursley.ibm.com/decimal/daconvs.html#reftostr