One thing about spending most of my time in the embedded-MCU world: I don't use floating point a lot.
But, what with the $2 MCU in one of the current projects having hardware floating point built right in at no extra cost... I figure, well, I might as well use floating-point calculations for stuff like calibration factors, because it's easier than mucking about with scaled integers, innit?
And besides, I'm using the KSDK implementation of printf, which never heard of my %p scaled-integer format. I miss my printf. I should port it to this platform. Anyway!
I enabled the floating-point formats in the print_scan module, and soon discovered that I was getting wildly wrong answers. Like, 10.0/65535 was coming out 1.000153, and (10.0/65535)*16985 was coming out 3.5917. Eh?
Well, it's pretty obvious that the actual arithmetic is right, but the formatting is wrong. Like, the integer part of the output is high by 1. But not always. Feed printf a nice clean constant 2.47, for example, and it comes out 2.47.
So I end up digging into mkfloatnumstr, where the actual conversion happens. There's some code that doesn't quite make sense, that's obviously the thing that's incrementing the integer part. Disregarding Chesterton, I boldly comment it out!
At this point, everything I throw at it works... except that 5.000 comes out as 4.000, and 10.000 becomes 9.000. Oh. Right.
[Added: These weren't actually exact numbers to begin with; the input was, e.g., 5, and the output being sent to printf was the nearest approximation the hardware was prepared to attempt. Which was probably 4.999something.]
Some rather common numbers, like 5 and 10, don't represent exactly as binary floating point. Thus, some fiddling is needed to make the binary version of 9.999999whatever come out as 10.
The original code having been rather less than useful, I just throw in a quick hack to check for fractpart > 0.9995, and figure that's good enough for the current application.
But methinks that module may need a rewrite... or at least that one function.
Somewhere around here I should have my totally portable floating-point formatting functions that I wrote back in the 1980s, for use on targets such as the 68000 and DG NOVA. Might just be time to look for them... and I hope they exist somewhere other than a 9-track tape.
Update: My first hack didn't work right, either; 2.75 plus quantization came out 3.75. Next try was waiting until after the fractional part had been converted, and checking for carry (leftover fraction >= almost 1).
Recent Comments