LPCXpresso 7.4.0 double floating-point issues

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

LPCXpresso 7.4.0 double floating-point issues

3,164 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ld0d on Fri Oct 24 09:11:59 MST 2014
I'm trying to use emulated double-precision floating point numbers with LPCXpresso 7.4.0 and the LPC4333 MCU.

For some reason the division operation gives incorrect results. For example the following C++ code:

static volatile double r2 = 2.0;
static volatile double rr = 1.0 / r2;

shows the result 'rr' as 0.25 in the LPCXpresso debugger, instead of 0.5.

What could be wrong? I'm using the FPv4-SP (Soft ABI) mode with NewlibNano (nohost), and I'm optimizing for size (-Os). This is a release build.

Edit: Example above is in C++. With 'float' instead of 'double', the result is correct.
0 Kudos
Reply
12 Replies

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by johnsonjeven on Wed May 11 23:45:38 MST 2016
Precision is the main difference where double is a double precision (64 bit) floating point data type and decimal is a 128-bit floating point data type.

Double - 64 bit (15-16 digits)
Decimal - 128 bit (28-29 significant digits)

So Decimals have much higher precision and are usually used within monetary (financial) applications that require a high degree of accuracy. But in performance wise Decimals are slower than double and float types. Double Types are probably the most normally used data type for real values, except handling money. More about......Decimal vs Double vs Float

Johnson
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Thu Mar 19 02:05:44 MST 2015
That is just an assignment to a global variable and shouldn't cause any strange effects.
If there is a glitch in the matrix it should be due to CGU_Init().
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ld0d on Thu Mar 19 01:58:13 MST 2015

Quote: JohnR
Maybe you are not allowing enough time for the line SystemCoreClock = clock_multiplier * 12000000 ??



That shouldn't affect the math emulation library... right? I found the issue originally in code that was executed much later in the program.


Quote: JohnR
If you place your two lines at  // TODO: insert code here would it make a difference??



Yeah, if it's C, you cannot do that (only constants can be defined there), and if it's C++, the calculation will be done before the main() function is reached.
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by JohnR on Wed Mar 18 08:45:35 MST 2015
Hi,

Maybe you are not allowing enough time for the line SystemCoreClock = clock_multiplier * 12000000 ??

If you place your two lines at  // TODO: insert code here would it make a difference??

JohnR



0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lyndaeldo on Wed Mar 18 00:23:18 MST 2015
The Decimal, Double, and Float variable types are different in the way that they store the values. Precision is the main difference where float is a single precision (32 bit) floating point data type, double is a double precision (64 bit) floating point data type and decimal is a 128-bit floating point data type.

Float - 32 bit (7 digits)

Double - 64 bit (15-16 digits)

Decimal - 128 bit (28-29 significant digits)

More about.......Decimal vs Double vs Float

Lynda
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ld0d on Fri Oct 24 13:54:04 MST 2014
I get the correct result if I single-step through __divdf3 instruction by instruction.
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ld0d on Fri Oct 24 11:01:14 MST 2014
Here is the failing example project.
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ld0d on Fri Oct 24 10:54:10 MST 2014
I was creating an example project, and found out that I only get the wrong result if the MCU is clocked at 96 MHz or higher.

To test this, I created an empty multicore project, set up the dual-bank memory configuration, and replaced main with this:

// TODO: insert other definitions and declarations here

// System clock configuration
extern "C" {
#include "lpc43xx_cgu.h"
}

int main(void) {

    const int clock_multiplier = 8;
    CGU_Init(clock_multiplier);
    SystemCoreClock = clock_multiplier * 12000000;

    static volatile double r2 = 2.0;
    static volatile double rr = 1.0 / r2;

    // Start M0APP slave processor
#if defined (LPC43_MULTICORE_M0APP)
    cr_start_m0(SLAVE_M0APP,&__core_m0app_START__);
#endif

    // Start M0SUB slave processor
#if defined (LPC43_MULTICORE_M0SUB)
    cr_start_m0(SLAVE_M0SUB,&__core_m0sub_START__);
#endif

    // TODO: insert code here

    // Force the counter to be placed into memory
    volatile static int i = 0 ;
    // Enter an infinite loop, just incrementing a counter
    while(1) {
        i++ ;
    }
    return 0 ;
}


With clock_multiplier=8 the result is 0.25, with clock_multiplier=7 or lower I get rr=0.5 like I should. Weird.
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Fri Oct 24 10:12:47 MST 2014
Whoops - late on a Friday for me...

Anyway, it works for me (see screenshot).

Can you provide an example project that shows it misbehaving?
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ld0d on Fri Oct 24 10:02:02 MST 2014
Yes, C++.
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by capiman on Fri Oct 24 09:45:33 MST 2014
C++ source file?
0 Kudos
Reply

3,082 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Fri Oct 24 09:41:09 MST 2014
Well, that code won't even compile for me:
../src/timer_main.c:55:2: error: initializer element is not constant
0 Kudos
Reply