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,
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.