|
|
View previous topic :: View next topic |
Author |
Message |
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Wed Mar 16, 2005 2:58 pm |
|
|
"No cop out " ???
Oh OK? Their are a lot of people here that can come up with a solution (hack) and even give a pretty good explaination of what went wrong (without the source code I might add) before a fix is given. You wouldn't believe how many companys will put things off because they are investing to much of their time on profit rather than fixing their broken problems.
"Maybe someone will organize an effort to make a free, open source PIC environment that's superior to CCS, Microchip, Hi-Tech et. al. For starters, it better handle 256 bit floats perfectly and better darn well have pointers to constants that use NO extra code space to implement . And it better work equally well on a 12C508 as an 18F8720! And don't forget - FREE!!!!!"
Now your saying you are expecting more from FREE then PAY?
I am sure many companys could have gotten together to form community groups by now. Why havn't they? I don't know. There are many success stories out there to prove the point. I'm sure it will happen sooner or later. The sooner the better.
Also, I am not sayin everything needs to be free. Open-source does not always mean FREE. _________________ -Matt |
|
|
bluetooth
Joined: 08 Jan 2005 Posts: 74
|
|
Posted: Wed Mar 16, 2005 3:13 pm |
|
|
Matt:
So sorry - I forgot to put the [HUMOR] .... [/HUMOR] around my "dream compiler"....
Enough of this!
Back to the original topic, it seems as though PCM has found the root of the problem.... maybe CCS will fix it sometime!
|
|
|
Darren Rook
Joined: 06 Sep 2003 Posts: 287 Location: Milwaukee, WI
|
|
Posted: Wed Mar 16, 2005 3:15 pm |
|
|
kda406 wrote: | but geez, it really shouldn't be that hard. |
If floating point math is really that easy to you then why not write your own routines. |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Wed Mar 16, 2005 3:20 pm |
|
|
take a search on the web. There are open-source projects out there. The more support they get, the sooner you can stop waiting. _________________ -Matt |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 16, 2005 3:22 pm |
|
|
To continue working on the problem, I looked at Microchip's AN670,
which tells how to convert floating point to ASCII decimal format.
I modified the AN670 source code as follows:
In floasc.inc, I added 3 more digits (digit_10, digit_1000, digit_1000)
so I could get more significant digits in the result. (The example only
has 4 and I increased it to 7).
Code: | cblock
digit_1000 ;Added this
digit_100 ;Added this
digit_10 ;Added this
ones
tenths
hundredths
thousandths
endc
last_digit set thousandths
cblock
digit_count
endc
SIG_FIG equ 7 ;Changed this to 7. It was = 4
|
Then in main.asm I changed the input value to be 3600.000
Code: | start
;Load input value of 3600.000
movlw 0x8A
movwf AEXP
movlw 0x61
movwf AARGB0
movlw 0x00
movwf AARGB1
movlw 0x00
movwf AARGB2
call float_ascii |
I also changed the processor to a 16F877 and changed the cblock address
in main.c to 0x40, where there is lots of RAM. Then I setup a Watch
window to see the output, and I assembled and ran the program.
The results were:
Code: |
digit_1000 0x33 3
digit_100 0x36 6
digit_10 0x30 0
ones 0x30 0
(decimal point here)
tenths 0x30 0
hundreths 0x30 0
thousandths 0x30 0 |
This shows the correct result of 3600.000, so this means the CCS
runtime code which does the same conversion in printf either has
a bug or maybe it has limited precision. The next step would be to
look closely at the CCS code and find out what's happening. |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Wed Mar 16, 2005 3:29 pm |
|
|
bluetooth wrote: | Matt:
So sorry - I forgot to put the [HUMOR] .... [/HUMOR] around my "dream compiler"....
Enough of this!
Back to the original topic, it seems as though PCM has found the root of the problem.... maybe CCS will fix it sometime!
|
I know where your coming from blue. It's humorous no matter what way you look at it. This all started from my humor. (the open source issue not the bug) _________________ -Matt |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Wed Mar 16, 2005 5:26 pm |
|
|
Point of information all whole numbers can be expressed as a power series
of 2 so it is no surprise that 3600 does also.
CCS floating point
8 bit exponent sign 23 bit mantissa
Now in theory since there are only 23 bits available numbers larger than 2^24-1 will only be approximated in practice due to hot dogging 24 bits are available by taking advantage of the fact that all binary floats will begin with a 1 in the mantissa.
Example
3600 is 111000010000.0 binary but in binary floating point it is normalized as 0.11100001 with an unbiased exponent of 11.
I know some will note there are twelve shifts but convention has the number one normalized as 0.1 with a biased exponent of 127.
Now for the naughty bit since all binary floats it will be 0.1 something we can hot dog and get the sign in there for free by replacing the first 1 with the sign and keeping in mind there is an implied 1.
Keen observers will see that we actually picked up a bit of precision by this hot dog process. That means we have 24 bits in a 23 bit space.
So we have 0110 0001 0000 0000 0000 0000 for storage or hex 61 0 0
now for the exponent we will be 11 shifts higher than the 127 bias which represents (2 power zero or one)
So the exponent is now 138 or hex 8A
the 4 bytes are hex 8A 61 00 00
So much for 3600 but its easier to understand if you look at the number one in float
it is hex 7F 0 0 0
the normalized mantissa is 0.1 binary but its hot dogged to 0.0 since all normalization starts with .1 and the sign is zero
so we have 0000 0000 0000 0000 0000 0000 for the mantissa. Since 127 represents two to the power zero the exponent is 127 hex 7f.
Are you ready for -1?
it is 7F 80 0 0 mantissa is 1000 0000 0000 0000 0000 0000
As I said in my earlier post the CCS error occurs in teasing out the ascii digits with divide by tens during printf
My math says any whole number between -16777215 and 16777215
can be represented by a float without imprecision . Printf should not be getting the trailing .999999 on these numbers this is not an imprecision issue its a bug in its float to ascii code. This is true for any number that can be expressed as a power series of 2 including negative powers. Ex 0.5 should print as 0.5 and 0.125 as 0.125 since they are negative powers of two.
All other numbers ie those bigger than 16777215 irrational numbers ( eg sqrt ) and rational numbers that aren't a power series of two eg 0.1) will be subject to issues many choose to describe as rounding. Its not the rounding your mother knows for that involves taking something to the nearest approximaion at a different level. Its really a fundamental issue with the expression of values in different number base notations. 0.1 in decimal cannot be expressed in binary with the precision it has in the decimal system. Its just how the universe works... 1/3 can't be expressed in decimal notation with precision either.
You should expect 10.0*0.5 to give you 5.0 but
10.0*0.1 to give you 0.999999x the later isn't strictly a rounding error its just the way floating point binary works. Its only accurate to 6 significant digits unless its a power series of two. |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Thu Mar 17, 2005 12:28 pm |
|
|
If you don't mind wasting the code space, I guess this would be an ok work around:
int i;
int digit;
float div;
int32 w = 3600;
float f;
f = w;
div = 1000;
for(i = 0;i<5;i++)
{
digit = f/div;
f-=(digt*div); //or f %= div; don't know if this would work with a float
if(i == 3)
printf(".");
printf("%u",digit);
digit/10;
}
You could also put a flag in there to get rid of leading 0's.
if (digit > 0)
set_flag = 1;
I have used this with other chips that did not offer a printf() with their compiler.
This code was from realled memory and has not been tested. _________________ -Matt |
|
|
kda406
Joined: 17 Sep 2003 Posts: 97 Location: Atlanta, GA, USA
|
|
Posted: Fri Mar 18, 2005 1:56 pm |
|
|
First I just have to reply to this:
Quote: | Quote: | but geez, it really shouldn't be that hard. |
If floating point math is really that easy to you then why not write your own routines. |
Darrin, sure it could be done, but then what am I paying CCS for? Like most, I have a reasonable expectation that software will work as advertised. If it does not, I have another reasonable expectation that it will be corrected, especially if I am paying for maintenance.
Next, I would like to give many thanks to the guys who looked so deeply into this issue, proving that it is indeed a bug. Also, I greatly appreciate the work around code suggestions. Although they may have compiled smaller than my code solution, I have to worry about the next programmer who comes along behind me understanding what appears to be insane antics in my code. Here is what I ended up doing:
Code: | int32 i32,w;
w = 3600;
// The below is a work around for yet another
// CCS bug, this time to do the equivalent of:
// printf(TERM,"%5.2f",(float)w/100);
i32 = w / 100; // Whole number
w = w - i32 * 100; // Remainder
fprintf(TERM,"Temperature in F: %lu.%02lu\n\r",i32,w);
|
At least it works dependably and the next guy will understand what I did and why. Thanks.
-Kyle |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sat Mar 19, 2005 4:29 pm |
|
|
Its unfair to expect someone to rewrite printf to get floating point printing working corrrectly. Most floating point numbers will have some unavoidable imprecision when expressed in the decimal system using printf....but thats not an excuse for artificially introducing error into numbers that can be expressed accurately since they are expressed as a power series of 2 up to 2^24. If he hasn't already I hope kda406 submits this as a bug to CCS. |
|
|
kda406
Joined: 17 Sep 2003 Posts: 97 Location: Atlanta, GA, USA
|
|
Posted: Thu Mar 24, 2005 1:29 pm |
|
|
Quote: | Its unfair to expect someone to rewrite printf to get floating point printing working corrrectly. |
Thank you, Douglas!
I just downloaded 3.222 and tried it on that. Same issue. So I made the following bug report program to illustrate the bug. Here is the program in its entirety. It prints 35.99 when run:
Code: | #include "18F8720.h"
#device ADC=10 // Use 10 bits for A/D conversion
#define SYSTEMCLOCK 11059200 //11.0592 MHz Oscillator
#use delay(clock=SYSTEMCLOCK)
#fuses EC_IO,PROTECT,NOOSCSEN,NOBROWNOUT,NOWDT,PUT,CPD,NOSTVREN,NOLVP,NOWRT,NOWRTD,NOWAIT,MCU,NOWRTC,NOWRTB,NOEBTR,NOEBTRB,CPB
///////////// General IO Pin Definitions /////////////
#define PIN_TERMXMIT PIN_C6 // XMIT pin to terminal
#define PIN_TERMRCV PIN_C7 // RCV pin from terminal
///////// IO Port Definitions /////////
#use rs232(baud=115200, xmit=PIN_TERMXMIT, rcv=PIN_TERMRCV, stream=TERM, DISABLE_INTS)
void main(void) {
float f;
f = 36.00;
fprintf(TERM,"%5.2f\n\r",f);
sleep();
}
|
I get the feeling that they don't monitor their own forum. So I hope maybe the bug report will get their attention. I have probably reported in the neighborhood of 30 real, repeatable bugs to CCS over the years. Not once have they e-mailed me back to say, "thanks, we have fixed it." So I don't know when we users can know that we can print FP numbers without work-arounds.
-Kyle |
|
|
|
|
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
|
Powered by phpBB © 2001, 2005 phpBB Group
|