13.7.2.3.6 EX editing 1 The EX edit descriptor produces an output field in the form of a hexadecimal-significand number. 2 The EXw.d and EXw.dEe edit descriptors indicate that the external field occupies w positions, except when w is zero in which case the processor selects the field width. The fractional part of the field contains d hexadecimal digits, except when d is zero in which case the processor selects the number of hexadecimal digits to be the minimum required so that the output field is equal to the internal value; d shall not be zero if the radix of the internal value is not a power of two. The hexadecimal point, represented by a decimal symbol, appears after the first hexadecimal digit. For the form EXw.d, and for EXw.dE0, the exponent part contains the minimum number of digits needed to represent the exponent; otherwise the exponent contains e digits. The e has no effect on input. The scale factor has no effect on output. 3 The form and interpretation of the input field is the same as for Fw.d editing (13.7.2.3.2). 4 For an internal value that is an IEEE infinity or NaN, the form of the output field is the same as for Fw.d. 5 For an internal value that is neither an IEEE infinity nor a NaN, the form of the output field is [ ± ] 0X x0 . x1x2 . . . exp where: • ± signifies a plus sign or a minus sign; • . signifies a decimal symbol (13.6); • x0x1x2 . . . are the most significant hexadecimal digits of the internal value, after rounding if d is not zero (13.7.2.3.8); • exp is a binary exponent expressed as a decimal integer; for EXw.d and EXw.dE0, the form is P ±z1 . . . zn20 , where n is the minimum number of digits needed to represent exp, and for EXw.dEe with e greater than zero the form is P ±z1 . . . ze22 . The choice of binary exponent is processor dependent. If the most significant binary digits of the internal value are b0b1b2 . . ., the binary exponent might make the value of x0 be that of b0, b0b1, b0b1b2, or b0b1b2b3. A plus sign is produced if the exponent value is zero. Examples: Internal value Edit descriptor Possible output with SS in effect 1.375 EX0.1 0X1.6P+0 −15.625 EX14.4E3 -0X1.F400P+003 1048580.0 EX0.0 0X1.00004P+20 2.375 EX0.1 0X2.6P+0
I will take this one.
*** Bug 96569 has been marked as a duplicate of this bug. ***
Interesting language if not sort of weird: "exp is a binary exponent expressed as a decimal integer" I am in early stages of choosing how to do this.
An Update. I have the front end and runtime parsing for OUTPUT done and am now looking at the actual implementation. We have the printf series of functions available and can use the %A format specifier to create the hexidecimal float string. I want to note here that on input, apparently the F editing requires one to be able to READ a hexadecimal float with the F descriptor as well as the EX descriptor. See 13.7.2.3.2 part 7. Another aspect I am studying has to do with rounding. On output I assume we must support RU, RD, RN vs truncating. Considering that the purpose of this type of representation of a float is mostly for "looking under the hood" I initially was thinking simple truncation should suffice and if a user does not know they have not specified enough precision for all hexadecimals, tough beans. After all, in hexadecimal, it is always an exact fit. I am curious what others think about this. Regardless, we will need a new rounding function to round the hexadecimals before output. On input, obviously we need to do a new read function and for the F descriptor we will have to look ahead to identify that it is a hexadecimal before processing it, otherwise it just looks like a bad float.
I have been studying this a bit by looking at the 2023 std and functionality of printf(). Specifically printf() provides the 'A' descriptor which can be used for float (kind=4) and double (kind=8). It will accept a long double (80 bit aka kind=10). I am noticing that the results of double and long double are identical, no extra precision visible. It is very possible I am not doing that correctly. I do not see anything related to quad precision floats. I am posting this as i think we will have to do some of our own translating byte portions of floats ourselves. Portability may be an issue. For example IBM 360 128bit precision or some other processor may not follow the same internal representations. Regardless I have preliminary code for the frontend that results in calling anew fucntion write_ex in transfer.c I think that kind=4 and kind=8 will be fine. Any thoughts on kind=10 or kind=16 I would appreciate as I further explore this.
(In reply to Jerry DeLisle from comment #5) > I have been studying this a bit by looking at the 2023 std and functionality > of printf(). > Specifically printf() provides the 'A' descriptor which can be used for > float (kind=4) and double (kind=8). It will accept a long double (80 bit > aka kind=10). I am noticing that the results of double and long double are > identical, no extra precision visible. It is very possible I am not doing > that correctly. > > I do not see anything related to quad precision floats. I am posting this > as i think we will have to do some of our own translating byte portions of > floats ourselves. Portability may be an issue. For example IBM 360 128bit > precision or some other processor may not follow the same internal > representations. > > Regardless I have preliminary code for the frontend that results in calling > anew fucntion write_ex in transfer.c > > I think that kind=4 and kind=8 will be fine. Any thoughts on kind=10 or > kind=16 I would appreciate as I further explore this. Just some thoughts: Have you tried "%LA" for long double? Have you tried quadmath_snprintf (https://gcc.gnu.org/onlinedocs/libquadmath/quadmath_005fsnprintf.html) with "%QA" for quad precision?
(In reply to Thomas Henlich from comment #6) --- snip --- > Just some thoughts: > > Have you tried "%LA" for long double? > > Have you tried quadmath_snprintf > (https://gcc.gnu.org/onlinedocs/libquadmath/quadmath_005fsnprintf.html) with > "%QA" for quad precision? That was the hint I needed. #include <stdio.h> int main() { float x = 1.0f / 3.0f; double y = 1.0l / 3.0l; long double z = 1.0L / 3.0L; printf(" FLOAT: %.18A\n", x); printf(" DOUBLE: %.18lA\n", y); printf("LONG DBL: %.18LA\n", z); printf(" 123456789012345678901234567890\n"); printf(" FLOAT: %.20f\n", x); printf(" DOUBLE: %.20lf\n", y); printf("LONG DBL: %.20Lf\n", z); } $ gcc hexfloat.c $ ./a.out FLOAT: 0X1.555556000000000000P-2 DOUBLE: 0X1.555555555555500000P-2 LONG DBL: 0XA.AAAAAAAAAAAAAAB000P-5 123456789012345678901234567890 FLOAT: 0.33333334326744079590 DOUBLE: 0.33333333333333331483 LONG DBL: 0.33333333333333333334 I will check the libqudmath version as well. Thanks.