1. Floating-Point
- Posted by Robert Craig <rds at ATTCANADA.NET> Mar 20, 2000
- 458 views
1. floating-point calculations are not always exact, and a tiny error in a calculation can be magnified into a huge error. floor(0.99999) is 0, as is floor(0.9999999999... trillion places) It is your responsibility as a programmer to properly handle these situations. 2. The number 0.1 and many others like it, can't be represented exactly in binary floating-point. You may get something like 0.09999999999999999 which leads to surprises when floor(10*x) is applied. The answer is not to seek out a binary f.p. software library that will give you trillions of digits of accuracy. That will just give you trillions of 9's. The answer is to apply a bit of rounding before you use floor(), or switch to Cobol. Even Cobol uses binary floating-point, but it also has something called "packed decimal" which has a few problems of its own. 3. When you subtract numbers of approximately equal magnitude, you are likely to lose a lot of accuracy. Subtracting two numbers that are accurate to 16 digits can easily leave you with a result that is only accurate to 14, 13, ... whatever number of digits. 4. All of the above applies to just about *any* programming language. It is a basic fact of life when binary floating-point is used. Intel and most other CPU's provide IEEE binary floating-point in the hardware. 5. By default, Euphoria prints numbers rounded to 10 significant digits. This is an arbitrary cutoff point that was chosen so as to not cause undue eyestrain or clutter. If you want to see more digits, use printf(1, "%.16e", x). 6. Euphoria is not doing anything mysterious. It is using IEEE binary floating point for all floating-point calculations. Careful line by line study of the Euphoria source code would tell you nothing about these basic issues of floating-point accuracy. Recoding your calculation in C, or some other language will likely give you the same results. 7. "But my pocket calculator never gives me these problems!" Calculators usually retain a few extra "guard" digits that they don't display. They show rounded results. They also typically use decimal floating-point. Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com
2. Re: Floating-Point
- Posted by Lewis Townsend <keroltarr at HOTMAIL.COM> Mar 20, 2000
- 431 views
- Last edited Mar 21, 2000
Hello Robert, Thanks for the info. I understand the problem very well now. >1. floating-point calculations are not always exact, and a tiny > error in a calculation can be magnified into a huge error. > floor(0.99999) is 0, as is floor(0.9999999999... trillion places) > It is your responsibility as a programmer to properly handle > these situations. I for one would almost rather recieve an error or a warning than allow subscripts be non-integers. Or perhaps the subscript error could have showed the original value instead of the floored result. This would help me to "properly handle these situations" by letting me know when they occur. Are you suggesting that we round everything to make sure this doesn't sneak up on us. >5. By default, Euphoria prints numbers rounded to 10 > significant digits. This is an arbitrary cutoff point that was > chosen so as to not cause undue eyestrain or clutter. > If you want to see more digits, use printf(1, "%.16e", x). My main confusion was that when I print()ed the results of the expressions it said 1 instead of .9999999999. Is that because of the 10 digit cutoff? Sure, I know, I didn't use printf() to get lots of decimal places but print() ROUNDED UP (to the nearest integer)! If print can do this, why can't the subscript mechanism? Would it slow things down? Sorry if this sounds like I'm whining. I'm just looking for more information. later, Lewis Townsend keroltarr at hotmail.com http://geocities.com/keroltarr/ ______________________________________________________ Get Your Private, Free Email at http://www.hotmail.com
3. Re: Floating-Point
- Posted by Everett Williams <rett at GVTC.COM> Mar 20, 2000
- 443 views
Robert Craig wrote: >1. floating-point calculations are not always exact, and a tiny > error in a calculation can be magnified into a huge error. > floor(0.99999) is 0, as is floor(0.9999999999... trillion places) > It is your responsibility as a programmer to properly handle > these situations. > >2. The number 0.1 and many others like it, can't be represented > exactly in binary floating-point. You may get something like > 0.09999999999999999 which leads to surprises when > floor(10*x) is applied. The answer is not to seek out a > binary f.p. software library that will give you trillions > of digits of accuracy. That will just give you trillions of 9's. > The answer is to apply a bit of rounding before you use floor(), > or switch to Cobol. Even Cobol uses binary floating-point, but > it also has something called "packed decimal" which has a few > problems of its own. Okay, but can we be assured that the floating point will always be less than the decimal. Less than or equal will cause rounding problems, but less than makes life reasonably easy. >3. When you subtract numbers of approximately equal magnitude, > you are likely to lose a lot of accuracy. Subtracting two numbers > that are accurate to 16 digits can easily leave you with a result > that is only accurate to 14, 13, ... whatever number of digits. There appeared to be a break at the 15th place on an item that was not a subtraction or other change. I still would like to know where the 17th thru 20th digits in Irv's printout came from. Those should be zero. If they are real, where did they come from? They appear to be an artifact of the print conversion routine. >4. All of the above applies to just about *any* programming > language. It is a basic fact of life when binary floating-point > is used. Intel and most other CPU's provide IEEE binary > floating-point in the hardware. True, as was noted earlier by me. That is why we need as much information as possible. When the hardware is difficult at best, the only protection we have is clear knowledge of the software. >5. By default, Euphoria prints numbers rounded to 10 > significant digits. This is an arbitrary cutoff point that was > chosen so as to not cause undue eyestrain or clutter. > If you want to see more digits, use printf(1, "%.16e", x). A note in the manual wouldn't hurt a thing. Guessing is hazardous to the accuracy of calculations. >6. Euphoria is not doing anything mysterious. It is using IEEE > binary floating point for all floating-point calculations. > Careful line by line study of the Euphoria source code > would tell you nothing about these basic issues of > floating-point accuracy. Recoding your calculation in C, > or some other language will likely give you the same results. Let's not be coy. Just because you don't wish to give it to us does not mean that it wouldn't tell us something about the accuracy of calculations. Better documentation would deflect a lot of these questions and requests. Simple order of instructions in any particular calculation can have huge effects on calculations where differences are small. The problem is that small differences can arise in intermediate calculations that can lead to totally spurious results. When one codes an equation, it is very difficult to control the status of all those intermediate results without very carefully breaking the equation into pieces and doing rounding at specific points. Needless to say the effect of that on efficiency isn't salutary either in the source or in the execution. Everett L.(Rett) Williams rett at gvtc.com
4. Re: Floating-Point
- Posted by Robert Craig <rds at ATTCANADA.NET> Mar 20, 2000
- 471 views
- Last edited Mar 21, 2000
Everett Williams writes: > Okay, but can we be assured that the floating point will > always be less than the decimal. No, you shouldn't assume that. It's really not as bad as it sounds. Just keep in mind that floating-point numbers are an approximation to the real numbers. Ask yourself "what if the result is a tiny bit higher or lower than mathematics says it should be? Will my code still work?" > I still would like to know where the 17th thru 20th digits > in Irv's printout came from. Those should be zero. > If they are real, where did they come from? They > appear to be an artifact of the print conversion routine. The print conversion routine does its best to convert from binary f.p. to a decimal representation. There is no reason why 0's should suddenly appear after 16 decimal digits. It's true that the digits after about 16 are pretty much random noise and should not be taken too seriously. It's pointless to print more than about 16 digits, given the current use of 64-bit f.p. Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com
5. Re: Floating-Point
- Posted by Everett Williams <rett at GVTC.COM> Mar 20, 2000
- 445 views
- Last edited Mar 21, 2000
Robert Craig wrote: >Everett Williams writes: > >> Okay, but can we be assured that the floating point will >> always be less than the decimal. > >No, you shouldn't assume that. > >It's really not as bad as it sounds. >Just keep in mind that floating-point numbers are >an approximation to the real numbers. Ask yourself >"what if the result is a tiny bit higher or lower than >mathematics says it should be? Will my code still work?" Having tracked down a problem relating to the change in float rounding from COBOL F to COBOL G, I can testify that small, but inconsistent differences can become huge over time. The case in point was a joint and reducing term life insurance calculation for mortgages. A change in the rounding technique in the last position did cause anywhere from no change to as much as 25% off, a matter of thousands of dollars. Any repetitive use of of a small error without forced rounding( and that would be very difficult in some of those calculations) can either cancel or swiftly take the calculation completely off course. The problem is anything but trivial and it effects a fairly broad set of problems. On the IBM, only calculations that absolutely required the float used it, because packed decimal was available and was completely dependable, though limited in scope and slow. snip >The print conversion routine does its best to convert >from binary f.p. to a decimal representation. There is >no reason why 0's should suddenly appear after >16 decimal digits. It's true that the digits after >about 16 are pretty much random noise and should >not be taken too seriously. It's pointless to print more >than about 16 digits, given the current use of 64-bit f.p. The routine should truncate or round at the last possibly significant digit...the 16th according to the manual. At the very least the manual should be corrected and an addendum be added with some of the effects noted. Not everybody has or will have experience with other languages where this is documented more thoroughly. Everett L.(Rett) Williams rett at gvtc.com