Maybe this doesn't belong on SO but I don't know where else.
I have to reimplement printf(3)
with C
without using any function that would do the conversion for me, I'm nearly done, but I'm stuck on %a
, I really don't understand what is happening here for example:
printf("%a\n", 3.0); //#=> 0x1.8p+1
printf("%a\n", 3.1); //#=> 0x1.8cccccccccccdp+1
printf("%a\n", 3.2); //#=> 0x1.999999999999ap+1
printf("%a\n", 3.3); //#=> 0x1.a666666666666p+1
printf("%a\n", 3.4); //#=> 0x1.b333333333333p+1
printf("%a\n", 3.5); //#=> 0x1.cp+1
printf("%a\n", 3.6); //#=> 0x1.ccccccccccccdp+1
Of course I read the man which says:
The double argument is rounded and converted to hexadecimal notation in the style[-]0xh.hhhp[+-]d, where the number of digits after the hexadecimal-point character is equal to the precision specification.
But this doesn't really help I don't understand the process that transforms 3.2
to 1.999999999999ap+1
I don't need any code but really more an explanation.
PS: If this isn't the place for this question could you point me to the right place?
EDIT: While @juhist
answer works for numbers >= 1.0
it doesn't explain how to get the result for numbers between 0.0
et 1.0
:
printf("%a\n", 0.01); //#=> 0x1.47ae147ae147bp-7
printf("%a\n", 0.1); //#=> 0x1.999999999999ap-4
printf("%a\n", 0.2); //#=> 0x1.999999999999ap-3
printf("%a\n", 0.3); //#=> 0x1.3333333333333p-2
printf("%a\n", 0.4); //#=> 0x1.999999999999ap-2
printf("%a\n", 0.5); //#=> 0x1p-1
printf("%a\n", 0.6); //#=> 0x1.3333333333333p-1
Also I would really like a precision on this The "a" near the end occurs due to limited floating point calculation precision
concerning the conversion: printf("%a\n", 3.2); //#=> 0x1.999999999999ap+1
EDIT2: Now the last mystery is to explain why in this case:
printf("%a\n", 0.1); //#=> 0x1.999999999999ap-4
The last 9
becomes and a
and in this case:
printf("%a\n", 0.3); //#=> 0x1.3333333333333p-2
The last 3
stays a 3
?