7 ms·
Because they do not for integer. The vast majority of languages you use out there that do not care about speed use Bigint. Python. Haskell. Ruby. Perl. PHP. Erl
by di4na 3y ago
Because they do not for integer. The vast majority of languages you use out there that do not care about speed use Bigint. Python. Haskell. Ruby. Perl. PHP. Erlang. Etc etc.
Floating point are used because quite simply they are the only way to do it that has wide support that can be reused.
A good fixed width or Decimal implementation that could be reused and implement all the maths you want for Reals are... Rare.
The exception is Java and JavaScript mostly. But JS has Bigint now. Just not as a default.
- zoky 3y agoI guess what I’m saying is that they should. We all grew up learning math before programming, and mathematically speaking, there is no qualitative difference between 15 and 14.7, and no difference whatsoever between 15 and 15.0. So why do programming languages, particularly ones like the ones you mention that purport to abstract such distinctions away, treat them differently by default? There is no logical reason why 5/2 should be 2 rather than 2.5, yet by default it is, for apparently no other reason than that is faster for the CPU to calculate. I’m not saying get rid of these distinctions entirely. But where they matter, for performance reasons or whatever, they should be opt-in rather than the default.
- defrost 3y agoIntegers are exact and give repeatable results. Many floats (such as 14.7) are not even represented exactly, float operations have a large number of issues. If you're wondering about all this, see: What Every Computer Scientist Should Know About Floating-Point Arithmetic ~ David Goldberg, March, 1991 issue of Computing Surveys https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.h... (and elsewhere)
- HPsquared 3y agoIt's a bit like musical scales. It all seems nice and neat, until you start looking for exactness.
- sfpotter 3y agoPlease don’t spread FUD about floating point arithmetic. IEEE754 is an extremely carefully worked out standard which provides a good trade off between speed and accuracy. The problem of representing a continuum of real numbers in a fixed amount of memory is highly nontrivial. The error incurred by each operation is bounded and predictable—not exact, but as good as you’re going to get given the constraints. Also, results are replicable. Speaking as someone working in numerical analysis and scientific computing, so I work with floats all day long.
- defrost 3y ago> Please don’t spread FUD about floating point arithmetic. I'm sorry, my apologies. Are you saying that IEEE754 does exactly represent 14.7 ? > Speaking as someone working in numerical analysis and scientific computing You're hardly the only Scot in Glasgow. I feel certain a few here abouts have arc'd through PDP-11's, Cyber 205's, and landed in modern centres such as Pawsey.
- sfpotter 3y agoNo, I’m not. In the applications IEEE754 was developed to support through standardization, being able to represent 14.7 exactly is simply unimportant.
- shadowgovt 3y ago... unless I have $14.70 in my bank account, and some naif was handed the job of writing the code to track that and didn't know about the non-intuitive consequences of relying on the IEEE floating point standard. Then its limitations suddenly become very meaningful to me or my financial institution.
- sfpotter 3y agoI guess you're right. We should throw the baby out with the bathwater because a bank hired a crappy engineer. There is no other solution to this problem.
- Gordonjcp 3y agoThe neat thing about floating point is that it works well to represent real-world values. It turns out that the real world is amazingly inexact, to the point that the inaccuracies of floating point just never even show up.
- vhcr 3y agoThat's exactly what the other commenters are arguing about. Why should 14.7 be not representable exactly when 15 is. With python you can use Fraction(147, 10) or Decimal("14.7"), but you have to explicitly opt-in.
- taeric 3y agoBut, go further. Why shouldn't 1/3 be represented exactly when 1/5 is? If it makes you feel better, with our current system, 1/256 is represented exactly. Using relatively few bits, all told. :D
- nyrikki 3y agoFractions, or the rationals are equivalent to polynomials. The rationals are also in aleph-naught, and thus have a one to one and onto mapping to the natural numbers. Floating point numbers are equivalent to rationals with their base as the denominator I. base-2 rationals with denominators that are powers of 2 will have termination expansions. Useful for storage but not arithmetic as Fraction(147/10) has 10 in the denominator and 5 is a prime factor that isn't in the base. BPD, or Binary Packed Decimal also allows for the storage of 14.7 But once again not useful for arithmetic. Accumulated errors, catastrophic cancelation, etc are real problems too. In decimal, 1/3 can be stored exactly but the expansion is 3 33333... Because 3 is prime and not a prime factor of 10. Had we decided on something rather than 10 for our base it may have worked out for computers better, but it is what it is. The rationals are nice, being the only countable, totally ordered sets. But producing a computer circuit that can perform arithmetic on them isn't practical as far as I know without using fixed radix and the associated problems with non-terminating expansions.
- lanstin 3y agoThe probability of a real number being exactly 14.7 is zero, so it is immaterial if you can represent hat particular real exactly, as long as the basic operations on the reals work as expected. Support for == between floats arguably should be removed, as it isn’t really a valid concept.
- sfpotter 3y agoThe probability of a real number equaling 14.7 depends on the specific distribution the real number is being sampled from. If X is a Bernoulli(p) random variable, and Y = 14.7*X, then P(Y = 14.7) = p. Support for exact equality between floating point numbers is a perfectly useful and valid concept and should *not* be removed. You can easily design a simulation such that if you run it twice, it will give exactly the same result bitwise. This can be utterly invaluable when debugging complicated numerical software.
- lanstin 3y agosampled from reality i guess I was implying. Whatever model you have that generated 14.7 depends on measurements from reality with a bit of error bars. I admit removing language support for == of floats is a bit of a wild idea, but it is conceptually sound, if not practical. I'd support keeping it in a test/debug package. Tho if you are looking at bitwise patterns, then I find memcmp or its equivalents to be needed, to handle Nan != NaN.
- sfpotter 3y agoNaN != NaN is very useful when debugging numerical software. NaN is a great placeholder value for things which don't have a clear default value to which they can be initialized. To your point, there are plenty of situations where a floating point number will be initialized to a magic constant (0, 1, infinity, so many others...). Beyond initialization, there are also loads of functions which frequently yield floating point constants which can reliably be tested for equality, like max(0, x). There are no error bars here. Exact floating point equality can usefully tell us things like "has this number changed", or more generally "has this special case occurred"/"have we reached a particular state". Removing floating point == isn't conceptually sound, and it isn't practical.
- Someone 3y ago> We all grew up learning math before programming, and mathematically speaking, there is no qualitative difference between 15 and 14.7 IMO, there is a huge qualitative difference between 15 and 14.7; 15 is an integer, while 14.7 isn’t. I also think most people would know that instinctively. Reason? I think most people learn arithmetic progressing more or less along these lines: - positive integers - non-negative integers (i.e. learning and understanding the concept of ‘zero’) - non-negative rationals - all rationals - decimal fractions - all reals Phrased another way: I would think the majority of people would learn to count to 15 long before learning what 14.7 means. Also, as sfpotter already said, switching to doubles only isn’t a panacea. Neither are bigints (won’t help representing the result of ⅓ exactly, for example), rationals (won’t help representing the typical hypothenuse of a triangle exactly, for example), or radicals (won’t help computing the area of a unit circle exactly) A CAS would help, but by then, you’re giving up lots and lots of performance. (that doesn’t mean I am a fan of languages that silently round integer division. Silently moving to bigints and rationals IMO can be a good choice, but silently moving from an exact type to an inexact one IMO never is)
- zoky 3y ago> IMO, there is a huge qualitative difference between 15 and 14.7; 15 is an integer, while 14.7 isn’t. Yes and no. The fact that one is an integer and one isn’t only really matters when considering them in the context of a set, e.g. when counting. But there’s nothing special about integers that affects how we use them relative to decimals. Multiply both of them by 10, and you’re back to integers. Divide them both by 10, and you’ve got decimals. It’s perfectly reasonably for all mathematical purposes to consider 15 and 15.0 to be equivalent to each other. This isn’t the case with computers, and that has nothing to do with mathematics.
- atq2119 3y ago> We all grew up learning math before programming Speak for yourself :)
- sigsev_251 3y agoC also offers some kind of Bigint, though C's _BitInt was standardized because it's useful for high level synthesis (otherwise you need a custom preprocessor or C++ templates).
- nsajko 3y ago_BitInt may offer longer bit widths than usual, however the width is still fixed (compile time constant).