Sponsored by Double Your Dating
Meeting Women Online "On The Cheap" view!
doubleyourdating.com - Here’s some killer free ways to stand out from the crowd if you're online looking for a lovely lady...
66 Comments
- raingrove, on 10/12/2007, -8/+34try this in your browser. type this in your URL bar:
javascript:alert(0.2+0.1);
this is how retarded floating point operations are on computers. - benc, on 10/12/2007, -0/+18Terribly misleading article, trying to convince naive programmers that it's a good idea to use IEEE 754 floating point for everything. It's not. Don't use a hammer when you need a screwdriver!
When you need to do modular arithmetic (which the article ridiculously claims is almost never), use an integer type. If you need more precision, there is a standard 64-bit int type. If you need even more, there are dozens of free long integer libraries out there that allow you to store arbitrarily large numbers with perfect accuracy. Ditto for decimal types.
Floating point definitely has its uses, but it's not always the right tool for the job. Making all numeric types floating point is a very poor design choice. - pak314, on 10/12/2007, -4/+190.1 cannot be written exactly as a binary fraction which is why you get this inexact results. It is the same thing as writing 1/3 as a decimal fraction (0.333333...) The pattern repeats forever so you have to truncate is somewhere.
- ExCornelius, on 10/12/2007, -2/+15http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html
Because oftentimes floating point arithmetic is not OK even for decimal applications. - crimson117, on 10/12/2007, -4/+13Yet another example of a popular submitter getting dugg to the front page with a lame article.
- kalleanka, on 10/12/2007, -4/+13"That expression won't exactly work with ints either."
What? He did _not_ add integers. So it's a no brainer that does not work with integers. - Vladek, on 10/12/2007, -1/+10Article incorrectly states:
"Largest power of ten: a 32-bit int can represent [...] -2^32...+2^32-1".
The correct range is -2^31...+2^31-1. You need one bit (out of the 32) for the sign, and one "slot" for the zero (hence the -1). - pak314, on 10/12/2007, -0/+9For a financial application, you should be integers of an appropriate unit like cents (or smaller) and then format it appropriately when displaying in dollars.
- fatdog789, on 10/12/2007, -2/+9Don't even bring the Professor into this. If the man can make a radio from coconuts and leaves, he damn well knows enough not to use FP when ints are called for.
Respect the Professer, fool! - Curufir, on 10/12/2007, -1/+7Setting up and tearing down an FPU on every context switch isn't free. On x86 you seriously don't want every process to be using floating point maths when integer maths is just as accurate.
- IHatePants, on 10/12/2007, -0/+6"For a financial application, you should be integers of an appropriate unit like cents (or smaller) and then format it appropriately when displaying in dollars."
Exactly. Or, better yet (if you're in an OOP environment), create your own "Currency" class.
I did this when re-engineering a Student Financial Aid system for a university (my code disburses a few hundred million a year to students at a big university). Here are a few suggestions as to how to implement one, if you decide to do it yourself:
1)Store all values internally as an integer, and then allow multiple accessor methods to return it in the requested representation.
2) Include overloaded arithmetic methods on the class or on a co-class. That way people can add an int value without jumping through a lot of hoops.
3) Make the class immutable and use a flyweight pattern to pool frequently used instances, and a factory method to return references to those instances instead of using constructors. In my financial aid application the most frequently used values are between 0 and 20,000, whole integers. I pooled those values from the beginning and saw a 90% increase in performance because I wasn't abusing my garbage collector.
These suggestions don't just apply to financial apps either. Any time to need to guarantee a certain precision, and the platform you're on doesn't support that precision, just create your own datatype. That's what OOP is there for. (Well, one of the reasons.) - inactive, on 10/12/2007, -0/+5Your calculator does not use binary floating point numbers. Most modern calculators do their calculations using the decimal system. It's much much slower but the problems noted above aren't apparent because the calculations are done in the same base we write the numbers in (base 10).
- chrispy, on 10/12/2007, -0/+4yah this guy doesn't know wth he's talking about. read a few articles by goldberg and made a wiki. sounds like its written by a freshmen in college for a report. i bet he got reamed by the professor
- lnxaddct, on 10/12/2007, -4/+8Yea, your example is a little misleading. You just happened to choose .1 which is a repeating decimal in binary. Try javascript:alert(0.2+0.3); and your result will be fine. Even the first result is fine for just about any case. If you were using base 10 and added 2/3 to 1/3 (.666666 + .3333333) you'd get .9999999, which is the same as 1, but since we're dealing with a finite size of bits, you need to cut off somewhere and round, so you'd get .99999999998 or something like that. Floating point numbers are really well designed, and are implemented with optimal results in mind. You're making a big deal out of nothing.
- Metasquares, on 10/12/2007, -4/+7If you're using a language that allows unsigned variables, such as C/C , you can use the sign bit to store values as well. Presumably, that's what the article meant.
- coding, on 10/12/2007, -0/+3"Admittedly Intel's Pentium design comes a poor third (because it has too few FP registers). But Intel is catching up."
Don't worry they don't sell the most CPUs or anything in any category. - BLayman, on 10/12/2007, -0/+3Though the description doesn't mention it, the article is specific to the programming language Lua. That's why the author makes such a big point of saying 64 bit floats can hold more integers than 32bit. Otherwise why not compare 64bit floats and 64bit Integers. I would hazard a guess that Lua does not have an Int64 datatype.
DigitalGopher both could have helped us a little by mentioning Lua and putting the article in context. - Shazam999, on 10/12/2007, -1/+4Word. I used to work with "programmers" that used floating point types for revenue and expense totalling. And they always wondered why the numbers never balanced...
- oepapel, on 10/12/2007, -0/+3"Example?"
I can give a similar example of where using fp values can get you into trouble that integers avoid.
When you are dealing with floating point values, there are special values that have predetermined outcomes during equality/comparison operations. The value "NaN" or Not a Number is defined such that NaN != x for any value of x (including NaN!)
Therefore define a,b such that a=NaN and b=any other value (including NaN)
Then you can expect these results
a < b false
a = b false
a > b false
a !=b true
You would think that a==b would be true but in fact a==b is false according to the IEEE754 spec. The rest are a direct consequence of the inability of a NaN to match another value.
So, if you wrote some code like this:
if (ab) then { ... }
else { ... // a must be equal to b }
You would have a subtle programming error that would elude many programmers. It is a logic error that is a direct result of a deviation in how floating point comparison is made relative to how integer comparison is made.
The exact same code is fine and comtains no logic error when a and b are integers. - seanmac, on 10/12/2007, -0/+3Wow, flashback to intro to logic...
Ahmed, -8 is -(2^3). - lietkynes, on 10/12/2007, -0/+2Lua, in fact, does only have a single Numeric type which is by default a double. You can compile it to use any other type, be it an int or something custom. And since Lua is designed to be a very simple, small but capable extension language, you don't really care what version everbody else is using. You just link your version to your program and use what is convenient for you.
The writer is not trying to make every programmer use fp arithmetic, he is just answering a common question of Lua users. Now if this is front page worthy, that is another question. - Soniti, on 10/12/2007, -0/+2Why would I look any smarter saying that I don't understand the article?
~Soniti - perfectfire, on 10/12/2007, -0/+2With an n bit 2's complement number you can only represent -2^(n-1) to 2^(n-1)-1. With an unsigned integer you can represent up to 2^n - 1, but you cannot represent -2^n - 1 because it is unsigned. The "sign" bit in 2's complement representation is part of the 32 bits. Everybody but Vladek needs to go back to beginning programming.
- mxcl, on 10/12/2007, -0/+2I dunno, but I expect you only wrote what you did to try and make yourself look smart.
- AhmedB, on 10/12/2007, -0/+2I attended an advanced C course before and the instructor mentioned a few things that I thought are 'basic' back then, but then when he started putting examples on the presentation, I thought, "Ok, this guy seems to know what he's talking about", among these points are...
1. When performing any mathematical operation, know the range for the operands and check if the mathematical operation is meaningful for this range of values. For example you cannot guarantee that a value that will be in the 0.0000000001 range is 'equal to' 0.00000000013, there's always a chance of a rounding error here or there messing up the numbers.
2. Unless you're programming for something that's highly sophisticated and precise, most likely you will not need equality operators for floats or doubles, most likely you will be comparing if error value/range is smaller/larger than a certain acceptable error metric. - Soniti, on 10/12/2007, -1/+3How much do you want to bet that 50% of the people that dugg this article only did it because they thought it would make them look smart?
~Soniti - hello2usir, on 10/12/2007, -0/+2Here's an article for anybody interested in the internals of the FPU.
http://www.website.masmforum.com/tutorials/fptute/
A little knowledge of assembly language is required to understand most of it, but the first chapter should be easy for laymen to understand. - HappyScrappy, on 10/12/2007, -0/+2Also, 2^n-1 is never a non-zero power of ten.
- ishmal, on 10/12/2007, -0/+2He missed two side effects of using floats that integers do not have.
1. Granularity at the edges. As you get closer to the high and low range limits, there will be larger and larger gaps in the series of numbers that can be represented.
2. Cancellation. Because two numbers must be "normalized" before adding or subtracting (align their decimal points), adding a very large number and a very small number will sometimes result in the smaller number having no effect at all in the result. So it can happen that: LARGE_FLOAT + SMALL_FLOAT == LARGE_FLOAT
An integer's more limited range is because that it can represent -every- integer in its range, and all additions and multiplications where the result is in range are perfect.
Basically, avoid the one-size-fits-all solution. Just understand the problem and apply the right tool for the solution. - hello2usir, on 10/12/2007, -0/+2== and != are complimentary binary comparison operators, and evaluate to either true or false. They are mutually exclusive and cannot both evaluate the same with the same inputs. When x == y, then it must follow that !(x != y). There are no exceptions, and that includes floating point numbers.
- Sanzhiyan, on 10/12/2007, -1/+2Actually your concern on granularity doesn't affect integers when stored ad floats..
The reason is very simple, 53 bits are more than 32 bits..
When rapresented as floating points, integers are those configuration of bits that have their less-significant "1" in a position at maximum equal than their exponent, if you count from the more-significant bit. Given that you have 53 position, and that you have exponents till 2^10 each integer that you can rapresent can be rapresented exactly. - HappyScrappy, on 10/12/2007, -0/+1The most popular programming languages don't have exceptions for floats. And rightly so, because it slows down the ALUs. I can't think of a single language that raises exceptions on illegal integer operations.
NaNs (signalling NaNs) are not silent and are there to keep you from losing track of the fact that you ran into a problem on the way without having to raise exceptions.
I hate exceptions anyway, they often end up not caught at the right levels and causing my program to quit.
Either way, my point is proven. I gave an example as to why floats were bad and 3 people told me how I was clearly wrong. This shows just how few people understand floats.
How about this one?
if (x == (x+1)) {blah}
You can't possible execute that {blah} block, right?
With floats, you can. With sufficiently large values, floats (and doubles) cease to change when you add one to them. This is a reason that Apple using doubles for systems times is completely stupid. Run long enough and time ceases to progress.
Floating point is one of the most misused programming constructs. - tmanka, on 10/12/2007, -3/+4I have personally run into this in an implementation of a financial data warehouse application, confused the crap out of me until someone pointed out that floats are not exact....what a thorn in my side that was.
- Hergio, on 10/12/2007, -0/+1I dont think the article is at all trying to say "use floating point all the time". Its just saying you can and its possible (and why) but there are some caveats to keep in mind.
"If you need more precision, there is a standard 64-bit int type" - How do you get more precision with an int? 64 bits would only get you larger ints, not more precise ints. - AhmedB, on 10/12/2007, -0/+1@seanmac, thanks for the correction, I was just counting a 2^0 as 1, but thanks, so in that case it's 4 bits = (n =0 to n = 3).
So yeah with n bits and a 2's complement it's
- 2^(n-1) to + 2^(n-1) -1 - lobrien, on 10/12/2007, -1/+2I dugg the article because it's a good topic, but the content falls well short of all sorts of interesting questions, like... well, how _do_ the operations time out on today's Intel and AMD cpus? and how much hit _do_ you take on float-int conversions?
- ThomasOkken, on 10/12/2007, -0/+1"(!(a==b)) is not the same as (a != b)"
Example? - SuperSloth, on 10/12/2007, -0/+1I don't think anybody is suggesting anything other than "use chars when you can, ints if you must, and floats when they can't be avoided". That's just common sense.
- oepapel, on 10/12/2007, -0/+1crap!
The comment system mangled my post because I used greater than's and lesser than symbols!
Let's try again... when a is NaN and b is any value (including NaN)
a < b is false
a <= b is false
a == b is false
a >= b is false
a > b is false
a != b is true
so code that uses this form:
if (a < b) { ... }
else if (a > b) { ... }
else { ... // a and b are equal }
will have a subtle bug. Also...
if (a < b) { ... }
else if (a > b) { ... }
else if (a == b) { ... }
will execute none of the three paths. If this was used for initialization of values or for performing a step that must be done exactly one time, this would be a hard logic bug to find. - inactive, on 10/12/2007, -2/+3Here's the thing that has always bothered me: how come my expensive computer tweaks out on floats, but my 99 ¢ calculator doesn't?
That being said, I've never written a program that needed ten-decimal-point accuracy, and if I did, I'd work around it the usual way. (through handling ints and making the digits a string with the decimal inserted) Come to that, do a Fibonnacci in Python; the only limit to how high a number can go is how much RAM you have... - SuperSloth, on 10/12/2007, -0/+1Frankly, this is not a programmer's problem. Leastwise, not an end-coder's problem.
A program should behave as expected. People expect floating point math in a computer to work the same as it does on the chalkboard. If it doesn't, the computer is misbehaving. It's not a problem with the programmer. It's probably not a problem with the hardware. It's probably not even a problem with the compiler. The language definition for float is flawed. That's a **language** problem.
If object oriented programming is to work at all, floats need to be normal numbers. If that means they must be intellignet enough to apply significant digits, then so be it. - lampehat, on 10/12/2007, -0/+1I'm not sure why anyone would want to use floating points for something that critically needs to be exact?
Anyone? - Novagenesis, on 10/12/2007, -0/+1That won't really work because you can't have an infinitely precise "Large Decimal Number" in a finite space. Our FPU is as effective as possible, considering the -concept- of a floating point number.
If you want an infinitely precise decimal number, it's very possible to create, even near-trivial.
It also requires a massive amount of structural overhead. For non-arbitrary length, it's just a matter of matching a pair of ints across a decimal point, and writing math functions to deal with operations on them.
It -is- a programmer's problem because programming languages (designed by programmers) make use of a near-accurate floating point system instead of a 100% accurate one. It makes no sense to blame hardware manufacturers for choosing to implement the floating points in hardware instead of software.
There -are- languages with infinitely precise decimal numbers... They're NOT floating points. If you can design a hardware-implementable floating point standard that contains the power and features of modern floating point, using a similar amount of memory (up to 128 bit would be acceptable to me, anyway), and with absolute or at least arbitrary precisions, then you could have your name in every CS textbook.
Till then, you're just pointing a coder's blame NOT to the language (which, while I'm not all for that, is acceptable on higher level languages that should handle it) but on the hardware itself, that just does what the software says. - oepapel, on 10/12/2007, -0/+1"Eh, no programming language worth its salt will let you get that far. When operations that use or produce NaN happen, the CPU/FPU will (by default anyway) raise an exception,"
Really? Try it in "C" language. It's true that division by zero can trigger an exception but calculations that result in overflow or underflow will NOT usually trigger. In fact, MOST "C" runtimes have a predefined value for NaN. According to you, just assigning this value to a variable should trigger an exception which is just plain idiotic.
Your comments only serve to show that the original story is correct that many programmers have a poor grasp of floating point. - hello2usir, on 10/12/2007, -0/+1wrong thread. bury
- hello2usir, on 10/12/2007, -1/+1Eh, no programming language worth its salt will let you get that far. When operations that use or produce NaN happen, the CPU/FPU will (by default anyway) raise an exception, and branching code that depends on the comparison is skipped and control is passed to the exception handler if one is present. (I mention CPU because this is not limited to floats either, as illegal integer operations also raise exceptions)
Any programming language that will let such illegal arithmetic operations silently slip under the radar is poorly poorly designed. Luckily there aren't many. So it's safe to assume that comparison operations will always behave as expected in these languages. You should never find yourself in a situation where you're comparing NaNs unless you do so explicitly. And aside from crashing, you will likely never get "in trouble" from using comparison operators on floats, because the branching code that depends on it will never execute (unless you let it). - asstroboy, on 10/12/2007, -1/+1"Largest power of ten: a 32-bit int can represent all integers exactly, up to: 1,000,000,000 (actually -2^32...+2^32-1)."
What a confusing statement... 32-bit can do 2^32 ~ 4e9, or 2^31 ~ 2e9 if you want sign. So the "largest power of ten" that can be stored is 9 in either case, and that's what TFA seems to be driving at. But then he says "(actually -2^32...+2^32-1)" -- which is not a range available to 32-bit (as Vladek points out), because -2^32 can't be represented. - stesun, on 10/12/2007, -1/+1how the hell did this get to the front page. he does not seem to have a clue whats he's talking about.
- dubwai, on 10/12/2007, -0/+0"2. Unless you're programming for something that's highly sophisticated and precise, most likely you will not need equality operators for floats or doubles, most likely you will be comparing if error value/range is smaller/larger than a certain acceptable error metric."
That's wrong. Look here:
http://www.cs.princeton.edu/introcs/91float/
The loss of precision can come into play with calculating tax on monetary values as small as a 1.09, or .75. - Reweave, on 10/12/2007, -4/+4Well, it's true that the binary representation of floating point numbers isn't suitable for calculations. But at the same time, someone who doesn't even know this and see FPA as "correct answer + noise" has no right to call himself a programmer.
It's first year material in _any_ IT course. -
Show 51 - 66 of 66 discussions



What is Digg?