From: SourceForge.net <no...@so...> - 2006-07-27 21:57:37
|
Bugs item #1520966, was opened at 2006-07-12 07:49 Message generated for change (Comment added) made by maartenbrock You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1520966&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Run Time Library >Group: fixed >Status: Closed >Resolution: Fixed Priority: 5 Submitted By: Mark Rages (markrages) >Assigned to: Maarten Brock (maartenbrock) Summary: PIC16 floating-point multiply bug (small numbers) Initial Comment: I ran into this bug while trying to implement a moving-average IIR filter on a PIC18F4550. I expect the following code to output numbers descending toward "0.0". void main() { float fpnum=1.0; InitializeUSART(); while (1) { fpnum*=0.01; printf_small(" %f\n",fpnum); } } But what I get is this: 0.01 0.0001 0.000001 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -2097152. -2435456. -292096. -1579200. -115792. -1157.919922 -11.579199 -0.115792 -0.001158 -0.000012 -0. -0. -0. -0. -0. and so forth. The excursion into negative territory repeats periodically forever. See attached file "output.log". Another data point: If I start the code at 0.0, the output remains at 0.0 forever. This is the expected result. $ sdcc -v SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.6.0 #4290 (Jul 11 2006) (UNIX) ---------------------------------------------------------------------- >Comment By: Maarten Brock (maartenbrock) Date: 2006-07-26 11:30 Message: Logged In: YES user_id=888171 Thank you. At first I interpreted your message as: don't touch, we are at code freeze. Anyway, it's fixed now in SDCC #4303. But I think there are a lot more of these issues in the floating point library. ---------------------------------------------------------------------- Comment By: Borut Razem (borutr) Date: 2006-07-25 19:31 Message: Logged In: YES user_id=568035 The last two messages were written almost in the same time, so I saw Maartens message only after I submitted mine. Maarten, it is great to hear that you have a solution. If you'll fix it in time, it will be included in the release. Borut ---------------------------------------------------------------------- Comment By: Borut Razem (borutr) Date: 2006-07-25 18:45 Message: Logged In: YES user_id=568035 Since is an old bug, if won't be fixed in sdcc 2.6.0 release. > I found the source code's ancestor in GCC (3.3 or earlier). The current gcc implementation is in gcc/config/soft-fp/mulsf3.c. It should be verified if the bug is fixed in the latest version and borrow the fix. Unfortunately the new code is highly macro driven and published under LGPL with runtime exception. I doubt that we can use the same source file without modifications. But maybe we can get the permission from FSF to modify it and reuse in under the same license... Borut ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2006-07-25 18:39 Message: Logged In: YES user_id=888171 I've got a solution for the C variants of __fsmul and __fsdiv. But not yet for the asm optimized verions. I also do not know if there are more places that have this bug. It all boils down to detecting overflow and underflow of the exponent and returning INF or 0.0. When I have the asm fixed I will commit. ---------------------------------------------------------------------- Comment By: Mark Rages (markrages) Date: 2006-07-24 21:37 Message: Logged In: YES user_id=11637 Thank you both for helping. That regression test looks good to me. Now, when's the bug going to get fixed... ;) ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2006-07-24 20:49 Message: Logged In: YES user_id=888171 There's a document in your doc directory but it doesn't help much. It's not difficult though as long as you use some sort of unix (linux, cygwin, osx). Native windows cannot run the used simulator. 1) Get a source copy of SDCC either as a snapshot or direct through subversion. 2) run ./configure and make 3) cd to support/regression 4) run make 'make clean' removes most generated files so you can start anew. If you have any more questions post them in the devel-list. ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2006-07-24 20:37 Message: Logged In: YES user_id=888171 There's a document in your doc directory but it doesn't help much. It's not difficult though as long as you use some sort of unix (linux, cygwin, osx). Native windows cannot run the used simulator. 1) Get a source copy of SDCC either as a snapshot or direct through subversion. 2) run ./configure and make 3) cd to support/regression 4) run make 'make clean' removes most generated files so you can start anew. If you have any more questions post them in the devel-list. ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2006-07-24 20:34 Message: Logged In: YES user_id=589052 Hello Mark, Yep, you'll find the doc for the regression tests at http://sdcc.sourceforge.net/doc/test_suite_spec.pdf but, to avoid duplicate work, the bug can be reproduced in the regression tests with: ---------8<------------------------------------------ /* bug1520966 "Floating-point bug with small numbers" */ #include <testfwk.h> #include <math.h> void testFloatOp(void) { volatile float a,b; float result; a = 2.04e-38; b = 0.01; result = a * b; ASSERT( fabsf(result) < 1.0e36 ); ASSERT( fabsf(result) < a ); b = 100; result = a / b; ASSERT( fabsf(result) < a ); } --------->8------------------------------------------ > So I don't think it's a new bug. Yes, I verified 2.5.0 is also affected. So it's not a new bug. (And apparently few people seriously use floating point with SDCC.) Unfortunately it affects TWO of the four basic math operations: Multiply and Divide. Most likely, as multiply and divide are also used within the transcendental math routines there will be cases where this propagates into the transcendental routines. ---------------------------------------------------------------------- Comment By: Mark Rages (markrages) Date: 2006-07-24 20:15 Message: Logged In: YES user_id=11637 I'd like to set up for regression tests and write a test for this. Is there any documentation for the regression test suite? ---------------------------------------------------------------------- Comment By: Mark Rages (markrages) Date: 2006-07-24 20:08 Message: Logged In: YES user_id=11637 The file in question ( http://svn.sourceforge.net/viewcvs.cgi/sdcc/trunk/sdcc/device/lib/pic16/libsdcc/float/fsmul.c ) hasn't changed in years. So I don't think it's a new bug. ---------------------------------------------------------------------- Comment By: Borut Razem (borutr) Date: 2006-07-24 13:26 Message: Logged In: YES user_id=568035 > I'd see this report as a candidate for a release critical bug? If it is an old bug, I then we can postpone it. If it is a new one: if it is a new functionality, introduced after 2.5.0, I think we can make a release without fixing it if it is an old functionality which worked in 2.5.0, then we are in troubles :-( Frieder and Mark Rages: can you please verify the status of this bug ASAP? Borut ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2006-07-19 12:05 Message: Logged In: YES user_id=589052 thank you for the excellent report! Unfortunately the bug is not limited to PIC16. The mcs51 also has it. I'd see this report as a candidate for a release critical bug? ---------------------------------------------------------------------- Comment By: Mark Rages (markrages) Date: 2006-07-14 02:56 Message: Logged In: YES user_id=11637 Here is a mail I sent to sdcc-user: The floating point routine in fsmul.c does not handle denormalized numbers well. I discovered this by doing: float f=1.0; while (1) { f*=0.25; } I expected f to decay to zero, but instead it wrapped around to a huge number! From looking at the source (device/lib/pic16/libsdcc/float/fsmul.c, but similar code for other architectures) I see there is no attemp at bounds checking when the exponents are being added together. So multiplying two numbers with very negative exponents can wrap to a very large positive exponent. It is also possible to get an infinite result, since the IEEE standard dedicates an exponent value to this. I found the source code's ancestor in GCC (3.3 or earlier). This code has the same problem in the multiply routine. Most GCC platforms have hardware floating-point support, so the code isn't used. In my code, I can work around this: #define SMALL_NUMBER 0.000001 float f=1.0; while (1) { if (f<SMALL_NUMBER) f=0.0; // see http://thedailywtf.com/forums/71684/showpost.aspx else f*=0.25; } I post this as a warning to others: Beware the floating point routines when you have numbers that may be close to zero! Regards, Mark markrages@gmail ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1520966&group_id=599 |