Trouble with operators and floating point numbers

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Trouble with operators and floating point numbers

647 Views
kevincronn
Contributor III

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?

Labels (1)
0 Kudos
3 Replies

587 Views
kevincronn
Contributor III

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.

0 Kudos

587 Views
Yuri
NXP Employee
NXP Employee

Hello, kevincronn 

   Comparison of floating point numbers, even for zero bytes, is not the same as for integer ones .   

Regards,

Yuri.

0 Kudos

587 Views
Yuri
NXP Employee
NXP Employee

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.

0 Kudos