I've noticed that sprintf seems to round the whole number part of doubles incorrectly. The below code loads string 's' with a value that seems to be rounded down to the closest 100 Hz. This causes my app grief, and I sure wish I could figure out how to use sprintf to print all the digits to the left of the decimal point correctly. Anyone have any advice on this question...? #define CRYSTAL (20000000.0) #define MUL (1401.0) #define DIV (255.0) #define MCK (CRYSTAL*(MUL+1.0)/(DIV*2.0)) double fClock = MCK; // debugger shows fClock as 54980392 sprintf(s,"%1.0f",fClock); // incorrectly loads s with "54980400" The funny thing is that I can use sprintf to load strings with "%11.09f" as the format string, and it's right 9 places to the right of the decimal point. I just can't figure out why it can't handle the integer part of double precision floating point numbers as well. Thanks, Seadog.
Try replacing the format specifier %1.0f with %.0f in case the field width of one is confusing sprintf. I'm assuming here that the ARM implementation uses 64 bit doubles?
Ian, I tried your suggestion, but it made no difference. Thanks, Dave.
"I tried your suggestion, but it made no difference." Just wondered, as I came across a bug in the C51 version of sprintf() a few years ago when using a field width smaller than that needed to output a value. What are you trying to achieve with the field width of one? Again, assuming that the ARM implementation uses 64 bit doubles it appears there is a bug in sprintf().
I was trying to output the whole part of a real number to a debug terminal by printing it to a string using that format string. And yes, I know there are other ways that I can accomplish this goal (which I've already done). It's just that I ran across something that looks like a KEIL library bug, and I wanted to let the KEIL folks know about it in case they might want to look into it and possibly fix it.
I've always had good results when submitting tiny projects that exhibit a bug to the tech support email address. While Keil employees do read the forum and respond, I'm not sure they consider it a formal source of bug reports or tech support requests. Posting here is a good way to let other users know about a problem and see if they have any insight.
"While Keil employees do read the forum and respond, I'm not sure they consider it a formal source of bug reports or tech support requests." It isn't: http://www.keil.com/forum/ http://www.keil.com/forum/terms.asp "Posting here is a good way to let other users know about a problem and see if they have any insight." Absolutely!
My bad... I should've been posting bug reports to tech support. I've posted this bug report there, and will post them there first in the future. Thanks for pointing that out. Dave.
Problem solved...! According to KEIL tech support, "The effect you see is due to the fact that Double Precision numbers are treated as single precision, in the CARM toolchain. Only the most significant 22 bits get stored. This is a normal single precision rounding effect." The suggestion was to use the new RealView compiler if I wanted double precision floating point support. I switched to the RealView compiler, spent a little over a day reading doc's, trying things, etc., and *finally* got my project to work with the RealView compiler (by starting a new project from scratch, importing all my files into it, and tweaking the ISR stuff a little). I'm still trying to figure out why I was not able to get my old project to work with the RealView compiler... it crashes the IDE every time I click on the "Download to Flash Memory" button. The end result is that now sprintf("%1.0f\r\n",MCK) produces the expected result, correct to the least significant digit of the whole part of the real (double precision floating point) number, MCK. Thanks KEIL tech support!
"Problem solved...!" It would have been solved a lot sooner and without the intervention of tech support if you hadn't ignored my attempts to get you to tell me whether the compiler supports 64 bit doubles.
OUCH!! Sorry for not doing the investigation you asked for right away. I did do it after the fact, and I'm further puzzled by what I found. According to the CARM compiler reference, the double data type does use 64-bits to store the values of variables. But, if you also search for 'precision' in the CARM reference, you'll find a reference somewhere else to the FLOAT64 compiler directive that must be used to enable double precision floating point math. Unfortunately, there's no mention of the need for the FLOAT64 compiler directive in the text for the double data type. A seeming contradiction is that KEIL's tech support response also included "The Keil CARM compiler currently does not support Double Precision Floationg Point (DPFP) numbers, and that support will not get added soon." So, in hindsight, it doesn't look a timely answer to your question would've helped solve the problem anyway, even if I would've found out about and used the FLOAT64 compiler directive. I did (and still do) appreciate your willingness to help resolve this issue. Pardon my ignorance, but I had assumed that a double was a double, and math using doubles would work as expected unless otherwise plainly indicated. If I ever have a reason to go back to the prior CARM compiler I'll try to remember to test the FLOAT64 directive just to see what happens. Currently, it looks to me like there's still a contradiction relative to what you can do with doubles and the CARM compiler. The bottom line... Per KEIL's suggestion I have upgraded to the RealView compiler, and the problem I was having with sprintf and math using doubles went away when I did that.
"OUCH!!" Er, yes, sorry, I hadn't had enough coffee this morning. I would guess that tech support are more likely to be correct than the manual and 64 bit doubles are not supported, but I'd be most interested to hear the result of your test.