Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
therat
PostPosted: Apr 30, 2012 - 01:26 AM
Hangaround


Joined: May 11, 2004
Posts: 152
Location: Canberra Australia

I am having a problem using the strtod function on a UC3A0. I am pulling a string from a text file that I then need to convert to a double using strtod. I have produced a short demo program to show what is happening that I have built with optimisation turned off. I am just testing this code in the simulator, but in my real program on the silicon I get the same results. Here is my sample code:

Code:

#include <avr32/io.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>


int main(void)
{
     double dbl;
     char szTmp[80];
    
     dbl = 0.9258696943694374;  // TRUNCATED - dbl == 0.925869694369437 after execution

     strcpy(szTmp, "0.925869694369437");
     dbl = strtod(szTmp, NULL); // CORRECT   - dbl == 0.925869694369437 after execution
    
     strcpy(szTmp, "0.9258696943694374");
     dbl = strtod(szTmp, NULL); // INCORRECT - dbl == 250.527019545547 after execution
   
    while(1);
}


Basically the problem is when I try to convert a string with 16 significant places strtod produces a completely incorrect result. In the simulator the second call takes a lot longer to execute (about 0.5sec for the first call and about 7sec for the second call).

The number I am trying to convert came from some javascript code that gives 16 significant digits. As a work around I am truncating the string of its last digit before calling strtod, but I would like to understand why this is happening.

Cheers
Simon
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Apr 30, 2012 - 02:36 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

Most likely, you're pushing the limit of precision. If memory serves me, double has a limit of approximately 16 significant digits, i.e. 16 digits or less depending on the value.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 30, 2012 - 09:29 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

If memory serves me, double has a limit of approximately 16 significant digits, i.e. 16 digits or less depending on the value.

That's true on "big computers" where "float" is 32bit IEEE754 and "double" is 64bit IEEE754. The first holds about 7.5 digits of accuracy and the second about 15..16 digits. But on avr-gcc float==double (that is they are both the 32 bit implementation) so you cannot expect to hold more than 7.5 digits

To OP, there are two AVR compilers with 64bit IEEE754 support. One is the $3,000 IAR compiler and the other is the $800 (is it?) "Pro" version of Imagecraft.

From time to time there's been talk of 64bit being added for "double" in avr-gcc but until someone steps up to the plate that remains a pipe dream.

avr-gcc does have uint64_t support so it may be possible to hold more digits of accuracy using integers if the number range fits.

For example hold:
Code:
double dbl = 0.9258696943694374

as
Code:
uint64_t l_long = 9258696943694374;

perhaps? uint64_t can hold up to 18446744073709551615.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
therat
PostPosted: Apr 30, 2012 - 09:51 AM
Hangaround


Joined: May 11, 2004
Posts: 152
Location: Canberra Australia

Yes, I agree I am pushing the limit of a double.

On the AVR32's using AS5.1 a double is in fact 8 bytes (64 bits). That is why I can get a precision of 15 digits in my sample code and it works just fine. Add a 16th digit and strtod magically breaks and gives a very strange result.

_________________
Simon
http://makin-things.com/
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Apr 30, 2012 - 10:18 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England

There may be potential for someone to port the 64bit code from the avr32-gcc to avr-gcc compiler perhaps?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
SprinterSB
PostPosted: Apr 30, 2012 - 01:15 PM
Posting Freak


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux

You are not using the last value of dbl. Maybe you are just folled by wrong/inexact debugging information?

Does code like the following pass or hit abort?
Code:
#include <stdlib.h>
#include <string.h>

#define AT __attribute__((noinline,noclone))
#define VAL "0.9258696943694374"

double AT test1 (void)
{
    double dbl;
    char szTmp[80];
    strcpy (szTmp, VAL);
    dbl = strtod (szTmp, NULL);
   
    return dbl;
}

double AT test1b (void)
{
    double dbl;
    static char szTmp[80];
    strcpy (szTmp, VAL);
    dbl = strtod (szTmp, NULL);
   
    return dbl;
}

double AT test2 (void)
{
    return strtod (VAL, NULL);
}

int AT test3 (void)
{
    return strtod (VAL, NULL) > 1.0;
}

int main (void)
{
    if (test1() > 1.0)
        abort();
    if (test1b() > 1.0)
        abort();
    if (test2() > 1.0)
        abort();
    if (test3())
        abort();

    exit (0);

    return 0;
}
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Koshchi
PostPosted: Apr 30, 2012 - 03:30 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13840
Location: Vancouver, BC

Quote:
On the AVR32's
Which means that this is the wrong forum for this post. This is an 8 bit AVR forum.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
cpluscon
PostPosted: Apr 30, 2012 - 03:44 PM
Raving lunatic


Joined: Jul 10, 2006
Posts: 2655
Location: Minneapolis

I compiled your code with gcc-4.3.3 and it worked OK.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits