| Details | Message |
|---|
Read-Only Author Zhi Chen Posted 4-Feb-2001 23:02 GMT Toolset C51 |  Inacurate precision truncating. Zhi Chen Hi folk, I have
u16 wTemp = 0;
fsingle fTemp = 17.5123;
wTemp = (u16)fTemp;
Somehow, the wTemp is 17. Technically, the wTemp should be 18, do anybody know what do I have to do for the compiler in order to generate more precise data conversion???
Thanks! |
|
Read-Only Author Dan Henry Posted 5-Feb-2001 04:57 GMT Toolset C51 |  RE: Inacurate precision truncating. Dan Henry I've always performed my rounding explicitly. For your example I would code it thusly:
u16 wTemp = 0;
fsingle fTemp = 17.5123;
wTemp = (u16)(fTemp + 0.5);
Adding 0.5 will round a float to the nearest integer for any float value, not just the value in your example.
--Dan Henry
|
|
Read-Only Author Andrew Neil Posted 5-Feb-2001 10:25 GMT Toolset C51 |  RE: Inacurate precision truncating. Andrew Neil "Technically, the wTemp should be 18"
No; 17 is correct: "When a value of floating type is converted to integral type, the fractional part is discarded" [1] (my emphasis).
That's precisely what "truncate" means!
[1] Appendix A, K&R, "The C Programming Language, 2/ed" |
|
Read-Only Author Mark Odell Posted 5-Feb-2001 13:50 GMT Toolset C51 |  RE: Inacurate precision truncating. Mark Odell No, integer casts on floats truncate so 17 is correct. Look up floor() and ceil() in your manual, they will help do what you want.
- Mark |
|
Read-Only Author Zhi Chen Posted 8-Feb-2001 23:28 GMT Toolset C51 |  RE: Inacurate precision truncating. Zhi Chen Thanks folks, I used Dan's method, it will definitely work for my situation. I know for sure my floating point is always positive numbers. Neither floor() nor ceil() will not solve the problem.
y = floor(3.53);
y will be 3, which is should be 4.
The round off should occur at 0.4 or 0.5
Unless my definition of round off is different than others.
Dan, How do you handle your negative values? |
|
Read-Only Author Andrew Neil Posted 9-Feb-2001 00:41 GMT Toolset C51 |  RE: Inacurate precision truncating. Andrew Neil My understanding is:
Rounding off should round to the nearest integer; Rounding down should round to the nearest integer below (ie, floor); Rounding up should round to the nearest integer above (ie, ceil)
So: for positive values, truncation is equivalent to rounding down; for negative values, truncation is equivalent to rounding up; for negative values, you would round off by subtracting the 0.5. |
|
Read-Only Author Mark Odell Posted 9-Feb-2001 01:28 GMT Toolset C51 |  RE: Inacurate precision truncating. Mark Odell So maybe he could do this:
int y = floatVar < 0.0 ? floor(floatVar) : ceil(floatVar);
What say you?
- Mark |
|
Read-Only Author Mark Odell Posted 9-Feb-2001 01:26 GMT Toolset C51 |  RE: Inacurate precision truncating. Mark Odell What about y = ceil(3.53); ?
|
|
Read-Only Author Dan Henry Posted 9-Feb-2001 06:49 GMT Toolset C51 |  RE: Inacurate precision truncating. Dan Henry Using the float type definition from your original post and assuming that the range of float input fits in an integer, I'd consider something like:
int round( fsingle fVal )
{
return ((int)(fVal + ((fVal < 0.0) ? -0.5 : 0.5)));
}
Regards,
--Dan Henry
|
|
Read-Only Author Mark Odell Posted 9-Feb-2001 13:03 GMT Toolset C51 |  RE: Inacurate precision truncating. Mark Odell I can't see with all the parenthesis!
:-)
int round(fsingle fVal)
{
return (int) (fVal + fVal < 0.0 ? -0.5 : 0.5);
}
Precedence is your friend.
Cheers.
- Mark
|
|
Read-Only Author Andrew Neil Posted 9-Feb-2001 15:21 GMT Toolset C51 |  RE: Inacurate precision truncating. Andrew Neil Good to see people who aren't afraid of the Ternary Operator! |
|
Read-Only Author Mark Odell Posted 9-Feb-2001 19:32 GMT Toolset C51 |  RE: Inacurate precision truncating. Mark Odell Indeed, I always tell people who say it obfuscates code that var++; is very odd at first glance as is var += value; ?: is very, very clear once the idiom is learned just as are var++ and var += value.
Long live all parts of the the C language.
Example use #234 of ?:...
int cash = 1;
printf("You have %d dollar%s\n", cash, 1 == cash ? "" : "s");
- Mark |
|
Read-Only Author Mark Odell Posted 9-Feb-2001 19:40 GMT Toolset C51 |  RE: Inacurate precision truncating. Mark Odell Of course this would have worked just as well I suppose:
int cash = 1;
char dollarStr[][sizeof "dollars"] = { "dollars", "dollar" };
printf("You have %d %s\n", cash, dollarStr[cash == 1]);
- Mark |
|
Read-Only Author Dan Henry Posted 9-Feb-2001 15:26 GMT Toolset C51 |  RE: Inacurate precision truncating. Dan Henry No, precedence is your friend; explicitness is my friend.
:-)
Over the years, and especially working with clients having pre-existing code, I've found (for me at least) that it's best not to pick nits over stylistic differences. To each his (or her) own. So, while I generally appreciate your informed posts, I won't engage you in discussing our sylistic differences.
Keep up the good work. We all appreciate your help around here.
--Dan Henry
|
|
Read-Only Author Mark Odell Posted 9-Feb-2001 18:53 GMT Toolset C51 |  RE: Inacurate precision truncating. Mark Odell I was definitely just ribbing you. I agree, to each his own.
- Mark |
|
Read-Only Author Zhi Chen Posted 12-Feb-2001 04:57 GMT Toolset C51 |  RE: Inacurate precision truncating. Zhi Chen True that folks, there is no need to talk about programming styles. In general, our team follow some sort of programming style pattern. This is due to programming skill differences among team members. So in general, making the program source code as explicitly as possible so that there is no misunderstanding and in addition, the C compiler will be smart enought to optimize "all" redundency.
|
|
Read-Only Author Andrew Neil Posted 12-Feb-2001 13:06 GMT Toolset C51 |  RE: Inacurate precision truncating. Andrew Neil "the C compiler will be smart enought to optimize "all" redundency."
You'd hope so, wouldn't you?
I did once come across a compiler (not 8051; not Keil; someone beginning with 'I') which did produce different results if you used "unnecessary" parentheses!
But then their assembler produced the same opcode for both the "Jump If Equal" and "Jump If Not Equal" mnemonics!!
|
|