MOD5213, atof convert"-0.0" to -2.0

Discussion to talk about software related topics only.
linhm
Posts: 18
Joined: Fri Sep 05, 2008 6:39 am

MOD5213, atof convert"-0.0" to -2.0

Post 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.
rnixon
Posts: 833
Joined: Thu Apr 24, 2008 3:59 pm

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

Post by rnixon »

What is the value of MAXADCCNTS ?

Have you tried casting it to float in your equation?
linhm
Posts: 18
Joined: Fri Sep 05, 2008 6:39 am

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

Post by linhm »

#define MAXADCCNTS 4095.0
linhm
Posts: 18
Joined: Fri Sep 05, 2008 6:39 am

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

Post 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));
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

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

Post 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.
linhm
Posts: 18
Joined: Fri Sep 05, 2008 6:39 am

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

Post 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.
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

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

Post 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
linhm
Posts: 18
Joined: Fri Sep 05, 2008 6:39 am

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

Post by linhm »

Thanks.
Mine is rel20_rc_4.
rnixon
Posts: 833
Joined: Thu Apr 24, 2008 3:59 pm

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

Post 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.
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

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

Post 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.
Post Reply