6 ms·
A couple of thoughts I've always had about floating-point arithmetic: 1. IMO it's unfortunate that most languages default to floating-point. Most programmers,
by svat 4y ago
A couple of thoughts I've always had about floating-point arithmetic:
1. IMO it's unfortunate that most languages default to floating-point. Most programmers, most of the time, would be better served by slightly slower but less confusing alternatives (it's nice that Raku uses rational numbers by default: similarly for integers, it's great that Python uses arbitrary-precision integers by default). At any rate, programmers would be a lot less confused about floating-point arithmetic if they had to opt in to it explicitly, e.g. instead of 0.1 + 0.2 if they had to say something super-explicit like (just exaggerating a bit for effect, this is probably impractical anyway):
NearestRepresentableSum(NearestRepresentable("0.1"), NearestRepresentable("0.2"))
till they got the hang of it.
2. IMO when explaining floating-point arithmetic it helps to add a picture, such as this one (added to Wikipedia by a user named Joeleoj123 in Nov 2020): https://upload.wikimedia.org/wikipedia/commons/b/b6/FloatingPointPrecisionAugmented.png https://upload.wikimedia.org/wikipedia/commons/b/b6/Floating...
With this picture (or a better version of it), one can communicate several main ideas:
- There are a finite number of representable values (the green points on the number line),
- Any literal like "0.1" or "0.2" or "0.3" is interpreted as the closest representable value (the closest green point),
- Arithmetic operations like addition and multiplication give the closest green point to the true sum,
- There are more of them near 0 and they get sparser away from 0 (the "floating-point" part),
etc.
Further, by staring at this picture, and the right words, one can infer (or explain) many of the important properties of floating-point arithmetic: why addition is commutative but not associative, why it is a good idea to add the small numbers first, maybe even the ideas behind Kahan summation and what not.
- trinovantes 4y agoIf nothing else, I think compilers/linters should warn when trying to use equality/comparison operators between floats since most of the time it's mathematically wrong. All of my projects are filled with isApproxEquals(float1, float2)
- kwhitefoot 4y agoThat really depends on where the floats come from and how they have been manipulated. I have written quite a lot of code where comparing floats was perfectly sensible. I had to repeatedly revert changes by colleagues who didn't understand the code and had replaced A == B with something like isApproxEquals(A, B). This was in electrical design software where every millisecond counted.
- adhesive_wombat 4y agoTo be fair, float point equality is often a red flag and often deserves a double-take (even if the result is, yes, it's correct). A comment like "exact equality is deliberate here and valid because XYX and important for meeting performance requirements ABC" would help, unless it's a major part of the system, in which case the colleague should know that already. And on their part, a check in with you for "hey, I don't understand why this equality is valid" would be better than assuming it's wrong and changing it.
- ycombobreaker 4y agoI see a lot of this (generic approx-comparison functions) at work. It can catch some problems, true, but it becomes very cargo-cultish. They understand that the hardware rounds calculations, but they behave as if the hardware is nondeterministic. There's also very little thought going into an appropriate epsilon value, whether based on the calculation being done, or the tolerance of the overall output/algorithm.
- codebje 4y ago> IMO it's unfortunate that most languages default to floating-point. Most beginning programmers would be better served … Most languages, most of the time, are not used by beginners.
- Kevcmk 4y agoAgree. But experts/intermediates often gloss over language semantics in pursuit if getting something done. For me, floating point by-default is more often a nuisance
- thethirdone 4y agoIf you are using "beginner" to refer to the time spent, this is true. However, if you use "beginner" to the knowledge gained, it might not be. If you only ever make webpages, even if you have made 100s you could still be a novice programmer because you never branched out enough to learn new programming concepts. If a programming language makes it easy to do something moderately, but it is hard to do it well. Programmers who only know that language are likely to have a gap in their stills. Floating point (in most languages) is easy to gets the basics working, but are hard to do well and very hard to do perfectly. This leads to a lot of programmers not learning floating point well.
- codebje 4y agoGeneral purpose programming languages are complex tools. In this specific case representing non-integer numbers effectively on a binary device is complex. If you use a different representation than IEEE floats you just give a different set of corner cases and unexpected outcomes. Don't let a novice build software you need to be correct without supervision, and if you are a novice expect to make mistakes, just like if I were to build a website I wouldn't expect my style choices to render appropriately on a wide range of devices... that's complex too!
- svat 4y agoWhether or not that's true, you can remove "beginning" from my statement as it's not necessary (done, just edited, thanks): most programmers, most of the time, don't need the speed of floating-point everywhere (compared to fixed-point/scaled integers, or rationals, or interval arithmetic, or whatever), and when they do, the language could let them easily opt into it with a declaration like "use float" or whatever.
- xigoi 4y agoThat would be another case of wasting a lot of time and electricity so the developer doesn't have to spend half an hour learning how a computer works.
- dahfizz 4y agoWhy should I have to learn how to do my job well? Programmer time is expensive! /s
- lizmat 4y agoThank you for your mention of the Raku Programming Language. If you want to force usage of floating point arithmetic, you will have to indicate that in literal values. E.g. `0.1` would be a [Rat](https://docs.raku.org/type/Rat https://docs.raku.org/type/Rat) (Rational number), and `0.1e0` would be a [Num](https://docs.raku.org/type/Num https://docs.raku.org/type/Num) (aka a floating point". In Raku, to get the nearest representation, use the [.narrow](https://docs.raku.org/routine/narrow https://docs.raku.org/routine/narrow) method. So `42e0.narrow`, `42.0.narrow` and `42+0i.narrow` would all be an `Int`. Yes, Raku has complex numbers built in as well :-)
- dahfizz 4y agoAny other way of representing the real numbers is going to have gotchas. Rational numbers take up more space and are slower to use, but also have real drawbacks like not being able to do sqrt or having to worry about overflow when doing a comparison. Ultimately, there is no substitute for knowing what you are doing.