We are seeing an issue with != and < > tests with floating point numbers. For instance we have the following test:
void KValUpdate(float a, float b)
{
if(a != b)
{
printf("Found changed kVal %5.2f : %5.2f\n", a, b);
if (QSPIIsBusy() != true)
{
KValErase(KVAL_ADDRESS1); // Write new values to flash
m_kValEraseInProcess1 = true;
s_flashUpdateInProgress = true;
kVal_ChangeTime_msec = 0u;
}
}
Every so often the if(a != b) test fails even though the values are the same. The print shows both values as being zero and a dump of the raw memory after a break point shows the values as 4 bytes of zeros, yet the test fails. Eclipse shows the assembly code to be:
if(a != b)
8080e040: vldr s14, [sp, #16]
8080e044: vldr s15, [sp, #12]
8080e048: vcmp.f32 s14, s15
8080e04c: vmrs APSR_nzcv, fpscr
8080e050: beq.n 0x8080e0d8 <KValUpdate+220>
Looks like a vcmp of registers s14 and s15.
I also changed the test to be:
if(a > b || a < b)
{
same as above
}
Assembly
if(a > b || a < b)
8080dfa8: movw r3, #26676 ; 0x6834
8080dfac: movt r3, #33080 ; 0x8138
8080dfb0: ldr r2, [sp, #12]
8080dfb2: lsls r2, r2, #2
8080dfb4: add r3, r2
8080dfb6: vldr s14, [r3]
8080dfba: movw r3, #27696 ; 0x6c30
8080dfbe: movt r3, #33080 ; 0x8138
8080dfc2: ldr r2, [sp, #12]
8080dfc4: lsls r2, r2, #2
8080dfc6: add r3, r2
8080dfc8: vldr s15, [r3]
8080dfcc: vcmpe.f32 s14, s15
8080dfd0: vmrs APSR_nzcv, fpscr
8080dfd4: bgt.n 0x8080e004 <KValUpdate+124>
8080dfd6: movw r3, #26676 ; 0x6834
8080dfda: movt r3, #33080 ; 0x8138
8080dfde: ldr r2, [sp, #12]
8080dfe0: lsls r2, r2, #2
8080dfe2: add r3, r2
8080dfe4: vldr s14, [r3]
8080dfe8: movw r3, #27696 ; 0x6c30
8080dfec: movt r3, #33080 ; 0x8138
8080dff0: ldr r2, [sp, #12]
8080dff2: lsls r2, r2, #2
8080dff4: add r3, r2
8080dff6: vldr s15, [r3]
8080dffa: vcmpe.f32 s14, s15
8080dffe: vmrs APSR_nzcv, fpscr
8080e002: bpl.n 0x8080e074 <KValUpdate+236>
This test also fails when a and b look to both be identical.
We are using hard floats:
CPUFLAGS=-mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4 -mthumb -mno-thumb-interwork
We are using the IMX6ULL processor.
We cannot figure out why these operators are failing on floats. Any help?
Yuri,
I understand about floating point numbers and precision but these fail when the raw value for both floats is 4 bytes of zero. The raw hex value is 0x00000000 for both floats.
Hello, kevincronn
Comparison of floating point numbers, even for zero bytes, is not the same as for integer ones .
Regards,
Yuri.
Hello,
The problem concerns accuracy of floating point numbers.
Floating-point arithmetic - Wikipedia
Accuracy of Floating Point Representations of Numbers - Mathonline
So, when using compare operators with floating point some accuracy should be
taken:
if (fabs(a -b) > epsilon) ...
Have a great day,
Yuri
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.