This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Dear all,
I'm confused about the use of constant expressions. Or is it a compiler bug for the TI ARM v5.04?
Here is the sample code with the corresponding result in the line comment:
static float fTest;
static unsigned short uTest;
static unsigned long lTest;
fTest = 0.04; // 0.04 --> OK
uTest = fTest * 1000.0; // 40 --> OK
lTest = fTest * 1000.0; // 39 --> WRONG
lTest = fTest * (float)1000.0; // 40 --> OK
lTest = (unsigned long)(fTest * 1000.0); // 39 --> WRONG
lTest = (unsigned long)(fTest * (float)1000.0); // 40 --> OK
------------------------------------------------------------------------------
Now my questions:
Best regards,
Stefan
Those are not constant expressions. A constant expression contains only constants, so the only constant expressions in your example are 0.04 and 1000.0
However, that's not where the issue is. To understand what you're seeing, you need to be aware of these facts:
Now, what's going on is that you are multiplying the single-precision variable fTest by a double-precision value 1000.0. This requires the compiler to promote the value in fTest to a double, which means adding a bunch of zeros on the end. The compiler then rounds the double-precision result, which has a lot of zeros at the end, so it doesn't round up. Then the value gets truncated to an integer type for assignment to an integer.
When you instead multiply by a float-typed value, the compiler doesn't promote to double precision, and rounding just so happens to round up, giving you the value you desire. However, you cannot rely on the value always being rounded up. When dealing with floating-point values, you must always be aware that the values you are using may not be exactly representable, so you will sometimes get values that are not-quite-exactly the "algebraically correct" result.
Thanks for your reply. Up to now the compilers I used did not handle double precision folating types, so I wasn't aware of the difference using the suffix 'f' or not. I will have to take of that now!
(You are right, it is not a constant expression I was listing in the example. It used to be one since the original code uses a macro for the fTest value.)
For me it's still remarkable that the result between lTest und uTest is different since the same rounding should take place before it gets trunctuated to the integer type
There is a rounding step for the multiplication, but conversion to integer values does not round, it truncates.
I know that the cast will trunctuate, your answer didn't answer my question. I will precise my comment:
"For me it's still remarkable that the result between lTest und uTest is different since the same rounding in the multiplication should take place before it gets trunctuated to the integer type"
That is odd, and I don't have a good answer for that. I'll have to ask around.