36

I understand why floats served a purpose in the past. And I think I can see why they're useful in some simulation examples today. But I think those example are more exceptional than common. So I don't understand why floats are more prevalent in simple simulations rather than very high precision integers.

A classic argument is that floats provide a greater range, but high precision integers can meet this challenge now. For example: with modern 64-bit processors, we can do fast integer calculations up to 2^64. The solar system is a little less than 10 billion km in width. 10 billion km divided by 2^64 is about 5 microns. Isn't being able to represent position within the solar system to the precision of half a human hair enough?

On the flip-side, rounding errors from floating calculations can present problems. You need to consider the scale of the calculations to make certain that you're not inadvertently introducing error to your simulation.

So why do personal computers even need FPUs anymore? Why not just leave floats to the supercomputers?

2
  • 4
    I thought it was a neet question if you really think about it, but then floating-point-gui.de/formats/fp et al, kind of gave me all I needed to know. But maybe that's not enough? I dunno, it satisfied my curiosity on this particular matter, but perhaps there's a better answer. docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html told me more than I wanted to know, and it's rather authoritative.
    – BrianH
    Commented Jan 16, 2014 at 21:47
  • 1
    All numeric types are susceptible to rounding errors. What type would you propose to use to avoid rounding errors?
    – phoog
    Commented Jun 23, 2015 at 21:26

11 Answers 11

49

Your argumentation against floating point numbers is very fragile, probably because of naivety. (No offense here, I find your question is actually very interesting, I hope my answer will also be.)

A classic argument is that floats provide a greater range, but high precision integers can meet this challenge now. For example: with modern 64-bit processors, we can do fast integer calculations up to 2^64. The solar system is a little less than 10 billion km in width. 10 billion km divided by 2^64 is about 5 microns. Isn't being able to represent position within the solar system to the precision of half a human hair enough?

You seem to make an implicit statement, according to which once we know the scale of our problem, we can use fixed point arithmetic with respect to this scale to solve that problem.

Sometimes, this is a valid approach, and this is the one picked by Knuth to implement distance computations in TeX. What makes the use of fixed point arithmetic pertinent in this case is that all quantities appearing within a computation are either integers or distances occurring in a typesetting problem. Because the field of applications is so narrow, it makes sense to choose a very small unit length, much smaller than what the human eye can perceive, and to convert all quantities into multiples of this unit. This leads to a very important result: in the typographical problems relying on this representation of numbers, we never need to multiply two lengths together, so that loss of precision caused by multiplications in fixed point arithmetic do not occur.

Most of the times, it is however a terrible approach, here are a few reasons why:

  1. There exists physical constants and you cannot always adapt their units in a sensible way.

    Consider your solar system setting. The gravitational constant is 6.67×10−11 N·(m/kg)2, the speed of light is 3.00x10+5 m/s, the mass of the Sun is 1.9891×10+30 kg and the mass of the Earth is 5.97219×10+24. In your fixed point setting, you will not be able to represent the gravitational constant to a satisfying precision. So you will change the unit. But by doing so, you have to replace each number—replacing well-known, familiar quantities, by cryptic values. Furthermore, it is very likely that finding a system to appropriately represent all constants you need might not even be possible. Think to quantum physicits working with infinitely small particles whose speed is near the speed of light.

  2. There exists mathematical unitless constants.

    The value of Pi 3.1415 (up to the 4th decimal place) without any unit attached. There is actually a lot of similar useful constants that cannot be accurately represented in an arbitrary fixed point system. In the solar system setting you described, we can represent Pi with 6 decimal places, which gives a terrible accuracy when computing the circumference of a planet orbit, for instance.

  3. In a fixed point system, we need to know in advance the size of the quantity you are computing.

    Assume that we still do not know the value of the gravitational constant. We would make a lot of measures and write a computer program to find an approximation of that constant. Unfortunately, in the solar system setting you described, the gravitational constant is represented by 0, which should be the, rather useless, result of our
    computation.

  4. Some mathematical functions will not work well with fixed precision arithmetic, because of their growth rate.

    The most important ones are the exponential and the gamma function, which practically means that every program working with anything else than polynomials will be flawed.

  5. In fixed point arithmetic, it is very hard to multiply and divide numbers correctly.

    This is because if we do not know a priori the size of the numbers, we cannot tell if their product will fit in the representation. That is, we would have to check manually for precision underflow before each multiplication.

Conclusion

While the conclusion of your question implies that fixed point arithmetic could be sufficient for all-purpose computations and that floating point arithmetic should be reserved to supercalculators, it is precisely the converse which is true: floating point arithmetic is a very good and very sensible tool for all-purpose computations, while fixed point will only do well in very specific, well analysed, cases.

7
  • 3
    I clarified that the value of Pi I gave is an approximation.
    – user40989
    Commented Jan 20, 2014 at 14:06
  • 2
    boy, i could really disagree with points 3 and 4. and, if you gotta lotta bits in your fixed-point representation (like 64 or 128), all you need to know that your numbers are below the ceiling. maybe by a few orders of magnitude. about point 4, a moving average computation will work better in fixed point Commented Mar 27, 2015 at 6:35
  • 1
    Every single one of your examples is of a scientific nature, which is exactly what OP suggested FPUs be reserved for. what does the average user use that's impossible to represent in a 64 bit signed/unsigned integer?
    – MarcusJ
    Commented Jun 16, 2015 at 5:23
  • 1
    @MarcusJ FPU is for scientific computations (in their broadest sense) and the OP suggests to use integers for some scientific computations (positions in solar system). Fixed precision is not easier (divide money in small fractions). What the average user might need is arbitrary precision arithmetic for basic algebra or FPUs if the exponential must be part of the mixture.
    – user40989
    Commented Jun 18, 2015 at 21:57
  • 2
    @5gon12eder TeX is a typesetting program, not a drawing program. IMHO the problem is rather the “hey let's write a LaTeX package to support graphics” approach, while it would be better to use a dedicated tool. That tool happens to exist, it is called METAPOST and bsdowl makes it easy to blend these images in a LaTeX document. Commented Nov 18, 2015 at 9:27
25

Because switching to integers doesn't solve anything. The problem with floats isn't that they have inaccuracies, it's that half the people using them don't pay any attention to what's going on. Those same people aren't going to pay proper attention to the units they are using when they use an integer, and a different set of screw ups will happen.

Repeat after me: There is NO silver bullet.

22
  1. Physical characteristics of the universe (like the number of atoms in it) are not useful to determine the boundaries of number sizes, because useful calculations exist using numbers having wider ranges.

  2. Floating point numbers are a tradeoff between accuracy and range. They deliberately give up some accuracy to achieve greater range.

2
  • 1
    In support of the "boundaries of number size" - huge divided-by slightly-less-huge possibly equals a small rational with lots of digits after the point. Perhaps something like 3.1415926... - a rational approximation of PI. As PI is an irrational number, there's no bound on how precise you might want to be - and therefore no bound on how large those integers might need to be. You could have integers larger than the number of quarks in the universe squared and it's still not enough to give perfect precision.
    – user8709
    Commented Jan 17, 2014 at 11:06
  • 1
    +1 for mentioning the dynamic range – SNR tradeoff in simple words.
    – ulidtko
    Commented Jan 19, 2014 at 12:27
12

Because most of the processors that you use in your day to day life are not modern day 64 bit processors with crazy fast integer calculations or an over abundance of space. Most of your processors are 8-16 bit devices which run things like your car, microwave, or watch.

Besides, what happens when you need to talk about a half of a unit, like a half of a gallon, or a half a human hair? Whole numbers are great, but then you end up talking in notations like 6.4216×1030 which, while accurate, isn't how humans naturally think.

10
  • 19
    Those 8-16 bit microcontrollers don't have FPUs either. Code written for those devices is more likely to eschew floating point numbers than code written for beefy desktop CPUs, using integers or fixed-point formats instead for performance and simplicity. Making integer math fast is much easier and cheaper than making fp math equally fast.
    – user7043
    Commented Jan 16, 2014 at 22:11
  • 2
    @AndrejaKo M4F is a 32-bit processor. en.wikipedia.org/wiki/ARM_Cortex-M Commented Jan 16, 2014 at 23:01
  • 1
    @AndrejaKo Interesting, I knew many ARMs have FPUs, but was under the impression that hard float is still a bit of luxury. But that's not quite what this answer is claiming. Also, do you know if performance is similar for other arithmetic operations? Integer division is expensive for integers too, especially when you do two instead of one. I'd expect addition to be more clear-cut in favor of integers.
    – user7043
    Commented Jan 16, 2014 at 23:02
  • 1
    @Daira Hopwood Note that I never claimed to be otherwise! Cortex M is however taking up space traditionally used by smaller 8bit and 16bit devices.
    – AndrejaKo
    Commented Jan 16, 2014 at 23:08
  • 1
    @delnan Well if I'm reading the documentation correctly, FPU addition (VADD.F32) takes one cycle. Most of integer ADD operations are also one cycle, so it's about the same (again, if I'm reading the documentation correctly).
    – AndrejaKo
    Commented Jan 16, 2014 at 23:19
11

I'm working on a report as I type this. One of the fields is a long milliseconds of duration that I got from somewhere else. This is going to be sent to Microsoft Excel and the duration units it uses is decimal days (1.25 = 1 day, 6 hours).

Sure, you can subdivide a range from the lowest possible value to the largest and have integer units stepping between them, but thats a really awkward unit to work with in most cases.

There are three times that come into play when working with computers:

  1. Time it takes to code
  2. Time it takes to run
  3. Time it takes to maintain

When working with integers rather than floating point, you're trading times 1 and 3 for time 2 to run faster. But here's the thing... I don't need it to run fast.

If there's a rounding error in the 10th decimal place in calculating a decimal time, thats fractions of a second that I don't care about (the report is HH:MM:SS - not HH:MM:SS.000). They don't get rounded into what I'm dealing with or presenting. Floating point is good enough.

Calculating the area of a circle for a graph or where pi finds its way into probabilities with only integers is not fun. Pi is not 3.

Its also faster for me to work with floating point in many places. 1.5 is 1.5 not (15 with a scale of 1). So I can write my code faster and the person maintaining it can read it faster and work with it.

If you need to use fixed point precision (money) or pure integer math for speed certain applications (simulating galaxies colliding and nuclear bombs), by all means, use them. But for most things, floating point is just fine if you really aren't dealing with those specialized situations.


That's just working with one end of the scale. The numbers that can be subdivided between 0 and 264 (or however many bits you are using). 264 is about 1019. But what if you need to work with 1020 or 10200? There are problems that work in this domain that aren't restricted to super computers. There are times when regular simulations and games use floats - often because of restrictions on the library, but they use them there too. Sometimes its just easier.

Related on gamedev.SE: About floating point precision and why do we still use it

1
  • Apple uses double representing seconds since a fixed start date to represent dates, and double representing seconds for time intervals. Accurate within a microsecond for the next 200 years. And it's simple. If I want 1.5 seconds I write 1.5.
    – gnasher729
    Commented Feb 4, 2016 at 23:43
10

Using a float instead of a high precision integer (with conversions!) is simply easier and faster. I can type in

float myVar = 0.15; //my value...

and move on to the rest of the logic of my simulation. I don't have to spend extra time thinking about converting to int and making sure that all of my scales are correct.

And the results end up being good enough. I'll happily trade speed of development over ridiculous levels of presumed, relative accuracy within my work.

1
  • If readability is the issue here, you can write Float myVar = "0.15". No need to "spend extra time thinking about converting to int and making sure that all of my scales are correct". Let a library do it.
    – Navin
    Commented Jan 12, 2015 at 23:28
6

Why do programmers still use floats? To the (generally good) answers which are already here, I would add:

Because most programming languages don't provide a "decimal" type, or at least don't make it as convenient to work with as a float. If they are built in to the language and convenient to work with, arbitrary-precision decimal numbers are much more intuitive and easier to work with than binary floating-point numbers, which give funny answers when you try to calculate things like 0.3 - 0.2.

Yes, you can use integers as fixed-point decimal numbers. Addition and subtraction work just fine, but extra steps are needed when doing multiplication/division (the result must be shifted up/down). That may have gained some performance 15 or 20 years ago, but on the CPUs of today, guess what? Just using floats is faster. Actually, floating point arithmetic is sometimes even faster than integer arithmetic!

5
  • 3
    +1. I think the fact that 0.1 doesn't mean "one tenth" but rather "some number in binary representation which is somewhat close to one tenth but not really" is a major design flaw in most modern languages. FP math is a niche requirement, you should explicitly request it from the language. Commented Jan 17, 2014 at 16:36
  • 1
    @JorgWMittag, you have a good point there. Perhaps the "non-intuitive" behavior of FP is because we write the numbers as decimals in our source code -- if we had to write them out as binary numbers with a decimal point, there would be nothing "non-intuitive" about them. I'm not seriously suggesting that would ever be a good idea, of course.
    – Alex D
    Commented Jan 17, 2014 at 20:10
  • We could also use decimal floating point numbers, that would be much more practical :-) Once you remind people of the existence of numbers such as π, they usually begin to understand what "limited precision and accuracy" means, but also convincing them that the representation of 0.1 is actually infinite is a whole different level. Commented Jan 18, 2014 at 14:43
  • 3
    Decimal floating-point numbers represent certain values more accurately than binary floating-point numbers, but are inferior in just about every way when dealing with numbers that are not of the form K*10^N for some moderate-sized integer mantissa K and exponent N.
    – supercat
    Commented Oct 21, 2014 at 21:22
  • @supercat You are right, of course. But what you should remember is that while mathematically there is nothing special about numbers of the form K*10^N, those numbers are of very special interest and utility to humans who have grown up in a culture where numbers are written in base 10, which probably includes all programmers and all software users. If a program's user interface displays (non-integer) numbers in base 10, there may be very good reasons for using a similar representation internally.
    – Alex D
    Commented Feb 11, 2023 at 16:49
6

Because sometimes even a 64-bit integer won't give you enough range.

For example, in the physics code I'm currently working on, I need to convert some molecular masses between grams per mole (which the input / output format uses) and kilograms per molecule (which the internal calculations need for unit consistency).

There are about 279 molecules in a mole, so this particular conversion involves multiplying or dividing the quantities by a factor of 1,000 × NA ≈ 6.022 × 1026 ≈ 289.

Sure, this particular issue could be handled in fixed point, simply by using different fixed-point numeric types for per-mole and per-molecule quantities, but that adds a lot of complexity to code that doesn't really need it. And this is far from an isolated case — the physics calculations themselves often involve multiplication with things like Boltzmann's constant ≈ 2-76. In theory, I could handle all of that by using a lot of different fixed-point types and keeping track of which numbers need to be stored using which type, but why bother? Floating point lets me use a single numeric type to store all of them.

Besides, the kicker here is that these molecular masses are ultimately based on experimental data. None of them are known to more than ten significant digits or so, and even that is way more than the precision of some other parameters that enter the calculations. Even single-precision floats would be more than enough to store them — although I'm actually using doubles because, well, there's no real reason not to.

2
  • General audio processing uses floats because these are sufficient and fast to compute, using higher precision than what 32bit float offers is purely useless; implementations said numerically "exact" would require much more processing power and might not fit real-time specs. Some specific implementations use fixed point, like for some (old) embeded platforms, but that's not the scope of your question. See http://broadcastengineering.com/audio/fixedpoint_vs_floatingpoint .

  • Most other signal processing & image processing algorithm implementations use floating point quite for the same reasons. Fixed-point or integer implementations are only derived from the floating point algorithms for specific purposes.

5
  • 2
    Actually, a lot of audio signal processing is done with integer DSPs. For speech, 16-bit sampling and integer processing is quite sufficient. For music, 24 bits is probably preferable: the Access Virus synthesizers use Freescale 24-bit integer DSPs. 32-bit float DSP doesn't buy you anything over 24-bit integer DSP. Commented Jan 17, 2014 at 12:47
  • Indeed there are a lot of embeded devices which use integer DSP and a lot of algorithms which are quite effectly derived to integer. Though, many softwares on general computing platforms process their audio/image/signal processing in float for the given reasons.
    – moala
    Commented Jan 17, 2014 at 13:02
  • The dedicated devices frequently have to do a LOT more processing, in a limited amount of time, than the "general computing platforms". The dedicated devices generally have far lower power and cooling budgets. Last time I looked, you couldn't put an Intel flagship processor in a pocket cellphone, because of the power and cooling requirements. Commented Jan 17, 2014 at 13:23
  • I don't use a single floating point number in any of my audio software because it's lossy, and frankly I don't know of anyone that does.
    – MarcusJ
    Commented Jun 16, 2015 at 7:14
  • @MarcusJ Floating point in itself is not lossy. That's computations or sampling that are lossy, and they are lossy both for floating point and for int. Avoiding floats does not save you from losing precision.
    – moala
    Commented Jun 16, 2015 at 16:20
0

If you want to have coefficients, floats are just better.

For example, 54.2% of 12442, you just do 0.542 * 12442.

Don't forget float are computed by a dedicated unit on the CPU, the FPU. They're obviously not better for embedded hardware, because they do consume more power, but they're very important in game programming and graphic programming.

In science and finance, float are not really liked because there can be data loss.

In scientific simulation, I believe they're not used, the GMP library allows you to make a float of 128 bits or even larger, you can theoretically have precision as large as you can take, at the expense of speed.

In real time simulation however, float are preferred. There are some precautions when using float number if you want to avoid data loss or error accumulating. For example blizzard use a deterministic way to change the game state as a multiplayer game of starcraft 2 is played, since only players orders are transmitted, and not unit positions.

Floats just have their application, they have pros and cons.

3
  • 1
    Why should 0.542*12442 not be possible with fixed point numbers? Why do you think that integers do not have a dedicated place on the CPU?
    – phresnel
    Commented Jan 20, 2014 at 15:30
  • 1) Because fixed point can be mere programming technique. 2) because there is nothing to optimize on int, or it's so trivial that it doesn't take a lot of transistors. Floats are tricky because there is a mantra and an exponent. And maybe other reason. Historically, floating point was not a native programming option, it was one of the thing microsoft implemented into its OS so it was better for developers.
    – jokoon
    Commented Jan 22, 2014 at 17:55
  • 1
    1.a) Of course they are easy to use. Just a matter of abstraction. And of course they are not a programming technique, but a type of data. 1.b) Heard of SSE and data parallel programming? 2.a) Yet you have dedicated areas on the CPU which do the math for you (e.g. the adder), otherwise a (general purpose) CPU would be non-functional. You also know that nowadays there are no FPUs on commodity x86 systems anymore? 2.b): Your text is full of misinformation. Please review the wikipedia entry for Floating Points (sidenote: also, it's "Mantissa", not "Mantra").
    – phresnel
    Commented Jan 23, 2014 at 7:18
-2

Many programmers are using floats because doubles are too slow or take too much memory. On good GPUs doubles are 4 times slower, while on "mediocre" GPUs (like all nVidia GeForce GPUs apart from the GeForce GTX Titan) can have up to 24x slowdown. Many GPUs don't support doubles at all. That's why many developers (especially working with consoles) are forced to use floats. This often results in rough graphics and choppy unrealistic animation.

Update (for people having problems with inference):

  1. The range of 64-bit signed integer is 2^63. The range of IEEE 754-2008 single-precision float is 2^(2^8)=2^256
  2. Thus, the range of a single-precision floating-point numbers is 2^193 = 12554203470773361527671578846415332832204710888928069025792 times bigger than the rage of a signed 64-bit integer.
  3. Single-precision floating-point numbers are not enough even for applications that don't require precise calculations (like animaion and games). Single-precision floating-point numbers are nearly unusable for anything requiring higher-precision, like physical simulation (even in games).
  4. 2 & 3 => 64-bit integers are very poor substitutes even for single-precision floating-point numbers.
12
  • Ah - so it's the fault of the HARDWARE! That's GREAT! It frees the developer from having to actually THINK so he can just sit in his cubicle and serve the whine! Feh! You want smooth and realistic, you do what it takes to get there! You want fast and accurate, you do what it takes to get there! Share and enjoy. Commented Jan 17, 2014 at 2:41
  • @BobJarvis not sure if you're kidding around, but the above answer is a good one. Single precision floating point is the way to go for most GPGPU applications
    – alrikai
    Commented Jan 17, 2014 at 3:39
  • 9
    question was about floating-point numbers vs. integers. A double is just a larger floating-point number.
    – DougM
    Commented Jan 17, 2014 at 4:14
  • 3
    Your update completely ignores that a 64-bit floating point number HAS LESS PRECISION THAN A 64 bit integer. Yes, you can delineate a greater range with a floating-point number given the same memory size, but that range comes at a loss of precision... and you don't give a reason WHY the trade is worthwhile. (If the biggest number I need fits in a 64-bit int, why would I use a float?)
    – DougM
    Commented Jan 17, 2014 at 19:06
  • 1
    @Ark-kun: Discrete division is a different operation from real-number division. Diving 100 by 7 yields a quotient of 14 and a remainder of 2, absolutely precisely. The fact that some programming languages use the same operator for both operations doesn't make discrete division "inaccurate".
    – supercat
    Commented Oct 21, 2014 at 21:19