I have the following C code:

Code:

double hourfraction = (double)((double)hour+(double)minute/60+(double)second/(60*60));


hour, minute and second are int and vary from 0 to 59 or to 23 (in case of hour). I'm trying to calculate the time as a fraction. The math is absolutely correct, at least on normal (i.e. not code) calculations.

However, when the time is 2:29:06, the Prizm computes that line of code... and returns 2.685 instead of the correct 2.485. When the time is, 2:31:40, it calculates 2.83(4) instead of 2,52(7).

Before writing this code, I wrote (some months ago) other code that used floats and doubles, for the Prizm. It was rather complex and gave wrong results too (it was meant to calculate the distance from Earth to Moon and big distances like that) but since I had used custom implementation of trigonometric functions, I thought the problem was that and I didn't care to solve it.
But now it seems the Prizm (or the compiler...) gets doubles wrong even on simple division and multiplication.
Hmm, that's really weird. Most definitely something up with the Prizm's libraries - I can't replicate that in a quick Linux gcc test. Perhaps a bug report is in order?
Yeah, I would say that somethings up with the compiler, our "libc" or libfxcg... but I don't see where libfxcg or the libc draft could be interfering, so I suppose it's GCC or libgcc.
gbl08ma wrote:
Yeah, I would say that somethings up with the compiler, our "libc" or libfxcg... but I don't see where libfxcg or the libc draft could be interfering, so I suppose it's GCC or libgcc.

It's probably that port of GCC, since that's what decides what the operators and primitive datatypes do. Anything else and I'd suspect the libs.
Everything I find about GCC floating point being broken is related to excessive precision. But the Prizm has no FPU, and I'm compiling with the appropriate flag for these situations, so I can't see what's causing the problem. Very very annoying, specially since I must use doubles to set the value of the OS alpha variables.
I'm rather baffled by this problem, especially since I had no troubles using software floats for Graph3DP compiled by PrizmSDK v0.3. For the sake of comparison, here are my CFLAGS and LDFLAGS:
Code:
CFLAGS=-m4a-nofpu -mb -Os -mhitachi -Wall -I$(PREFIX)/include -L$(PREFIX)/lib -std=c99 -fno-strict-aliasing -ffunction-sections -fdata-sections
LDFLAGS=-Os -I$(PREFIX)/include -L$(PREFIX)/lib -T../common/prizm.ld -Wl,-static -Wl,-gc-sections -nostartfiles -lc -lgcc -lm
And mine (I made make echo the flags at compile time just to make sure I was seeing what it was in fact executing):

Code:

CFLAGS=-std=c99 -Os -Wall -mb -m4a-nofpu -mhitachi -nostdlib   -I/home/gabriel/Development/Casio-Pro/fixedSDK/projects/utilities/build -I/home/gabriel/Development/Casio-Pro/fixedSDK/include -D__GIT_VERSION="vBeta8-14-g2174-dirty" -D__GIT_TIMESTAMP="Wed, 13 Mar 2013 17:33:49 +0000"
CXXFLAGS=-Os -Wall -mb -m4a-nofpu -mhitachi -nostdlib   -I/home/gabriel/Development/Casio-Pro/fixedSDK/projects/utilities/build -I/home/gabriel/Development/Casio-Pro/fixedSDK/include -D__GIT_VERSION="vBeta8-14-g2174-dirty" -D__GIT_TIMESTAMP="Wed, 13 Mar 2013 17:33:49 +0000"
LDFLAGS=-mb -m4a-nofpu -mhitachi -nostdlib -T/home/gabriel/Development/Casio-Pro/fixedSDK/common/prizm.ld -Wl,-static -Wl,-gc-sections


To compile the problematic code only the CXX and LD flags are used.
You have some flags I don't have (and I have -nostdlib which you don't seem to have), I may try adding them and seeing if that fixes the problem.

EDIT: no, adding your flags didn't help.
To pinpoint a problem, you could try several mathematically equivalent expressions to see if they calculate differently.
Also try to use more and less explicit double conversions.
Also, does it always gives wrong result, or for some triples of (h,m,s) it gives correct result?
Here is a list of things to try:

Code:
/* original */
double hourfraction = (double)((double)hour+(double)minute/60+(double)second/(60*60))

/* variants */
double hourfraction1 = ((double)hour+(double)minute/(double)60+(double)second/(double)(60*60));
double hourfraction2 = (double)((double)hour+(double)minute/(double)60+(double)second/(double)(60*60));
double hourfraction3 = (double)hour+((double)minute+(double)second/60)/60;
double hourfraction4 = (double)hour+((double)minute+(double)second/(double)60)/(double)60;
Hmmm, I think nsg has the right idea there. It would be easiest to track this down if we can pinpoint exactly which mathematical operation is generating the error (or if it's several of them).
I just found out that if I set the values in code, like this:

Code:
ihour = 1; iminute = 20; isecond = 30;
fhour = ihour; fminute = iminute; fsecond = isecond; fmillisecond = imillisecond;
hourfraction = fhour+fminute/60.0+fsecond/(60.0*60.0);

...the result is the adequate hour fraction. However, if I use RTC_GetTime to set the values of the unsigned ints...

Code:
RTC_GetTime( &ihour, &iminute, &isecond, &imillisecond );
fhour = ihour; fminute = iminute; fsecond = isecond; fmillisecond = imillisecond;
hourfraction = fhour+fminute/60.0+fsecond/(60.0*60.0);

...it will give wrong results.
Now I really don't know what to do... it's not the floating point that is wrong anymore, but this is even stranger.

I also noted that the drift between the correct result and the result it returns gets higher as it gets later into the day. For example, at 00:06:21, it calculates the fraction that corresponds to 00:06:33; but at 16:08:18, it calculates the fraction that corresponds to 22:08:24.
I'll try not using RTC_GetTime but rather accessing the RTC registers and see what gives.
What if you were to go the other way, expressing the quantity in terms of seconds instead of hours, e.g., 60²*H+60*M+S?
With seconds, it shows the same drift, calculating the seconds for when it is 22 when it is 16... oh well, I'm going to use RTC registers.
EDIT: with RTC registers it works. I'm not going to care much more about this now...
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement