Page 1 of 2

MOD5213, atof convert"-0.0" to -2.0

Posted: Thu Aug 16, 2012 6:54 am
by linhm
Hello every friends here,

It's been a long time I have not posted questions. However lately I found some bugs in the firmware I developed for the MOD5213 module. Apparently the atof() function convert "-0.0" to -2.0 instead of 0.0.

Also the following code gave me a huge negative number instead of 0.0, where x,a,b are float, range is char, MAXADCCNTS is 4095.0:
x = (a - b) / (MAXADCCNTS - ((range == 1) ? 819.0 : 0.0));

if I modify the above code by using a temperory variable then I can get the correct result:

float xx;
if (range == 1) xx = MAXADCCNTS - 819.0 ;
else xx = MAXADCCNTS;// 4095.0
x = (a - b) / xx;

Does anyone have similar experience?
Is it caused the compiler?

Thanks.

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Thu Aug 16, 2012 8:45 am
by rnixon
What is the value of MAXADCCNTS ?

Have you tried casting it to float in your equation?

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Thu Aug 16, 2012 10:13 am
by linhm
#define MAXADCCNTS 4095.0

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Thu Aug 16, 2012 10:27 am
by linhm
Casting does correct it, but don't know why? BTW, a=-1.0, b=-1.0;
x= -166194084 without casting.

x = (a - b) / (float)(MAXADCCNTS - ((range == 1) ? 819.0 : 0.0));

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Thu Aug 16, 2012 11:32 am
by tod
I would suggest following rule #1 from Effective C++, prefer const to #define. If you replace your #define with

Code: Select all

const float MAXADCCNTS = 4095.0;
I suspect you will get the correct answer. Plus you will explicitly state the type as float instead of allowing the precompiler to make it a double (with the subsequent loss of precision when things get converted).

Your code as posted won't even compile for me when I use a #define, maybe I did something wrong but a short complete compilable example from you would have helped.

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Thu Aug 16, 2012 1:50 pm
by linhm
Thanks for all the replies.

I also tried casting to double as follows. This code gives the same error as without casting.
I guess it might be the defects in the compiler.
I understand that using "const float MAXADCCNTS = 4095.0;" is better practice.
But i don't think it will solve my problem.

#define MAXADCCNTS 4095.0
float a = -0.1;
float b= - 0.1;
char range = 0;

x = (a - b) / (double)(MAXADCCNTS - ((range == 1) ? 819.0 : 0.0));


As for the atof(), i made a workaround for strings like "-0.0".
I really want to know if anyone has this atof() problem before.

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Thu Aug 16, 2012 2:27 pm
by tod
So here's a compilable example

Code: Select all

    void TestAgain()
    {
#define MAXADCCNTS 4095.0
        float a = -0.1;
        float b = -0.1;
        char range = 0;

        float x = (a - b) / (double) (MAXADCCNTS - ((range == 1) ? 819.0 : 0.0));
        std::cout << "Testing define with cast:" << x << " \n";

        double test = atof("-0.0");
        std::cout << "Testing atof:" << test << "\n";
    }
When called on a MOD5272 it produces

Code: Select all

Testing define with cast:0
Testing atof:-0
If the cast is removed the results are the same.
If the #define is removed (and the cast) and const double used the results are the same.
I then ran it through a HelloWorld example for the PC and the results are the same.
I'm using NNDK Rel_2_6_0_020

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Fri Aug 17, 2012 8:08 am
by linhm
Thanks.
Mine is rel20_rc_4.

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Fri Aug 17, 2012 8:55 am
by rnixon
Hi linhm,

Your comments here seem confusing to me, but I would really like to know how this works. Please see below:
linhm wrote:Thanks for all the replies.

I also tried casting to double as follows. This code gives the same error as without casting.
I guess it might be the defects in the compiler.
I understand that using "const float MAXADCCNTS = 4095.0;" is better practice.
But i don't think it will solve my problem.
The original question was for float, not double. If you use the const method like Tod said, doesn't that solve the problem if you use float?

If you really want to use a #define rather than a typed constant, you might be able to use:
#define MAXADCCNTS ( (float) 4095.0)

Just out of curiosity, what type of data are you processing that needs the resolution of a double instead of a float? Of course, if something is wrong with double in the compiler it should be fixed.


#define MAXADCCNTS 4095.0
float a = -0.1;
float b= - 0.1;
char range = 0;

x = (a - b) / (double)(MAXADCCNTS - ((range == 1) ? 819.0 : 0.0));


As for the atof(), i made a workaround for strings like "-0.0".
I really want to know if anyone has this atof() problem before.

Re: MOD5213, atof convert"-0.0" to -2.0

Posted: Fri Aug 17, 2012 11:42 am
by tod
I would suspect the compiler tool chain has not changed from the 20_rc4 release (at least the directory names which have version numbers haven't changed.). I always find it valuable to have MinGW installed. I use its toolchain for standard C++ projects (like HelloWorld). This allows you to isolate any anomalies that are strictly part of the cross-compiler toolchain for the m68K family. As I've said I can't replicate either of your problems using either the MinGW toolchain or the m68K toolchain. I also don't have your processor but unless it uses different libraries for math that shouldn't matter. In the past I have seen compiler problems that are optimization dependent. This seems unlikely in your case but the default is -O2 and -falign-functions=4, if you're using something different that would be key information. You could try turning the optimization level to None(-O0) and see if the behavior changes.

In case it isn't obvious I would like to point out that a literal defintion like

Code: Select all

float x = 1.0;
results in a conversion from double to float.

You can avoid this by using the float literal suffix 'f'.

Code: Select all

float x = 1.0f;
The default precision for a floating point number is always double. So even

Code: Select all

#define SOME_SYM = 1.0
float x = SOME_SYM;
results in a loss of precision conversion, since the pre-processor turns this into the first example.