5 ms·
TL;DR; 0.1 in binary, is a repeating decimal - just like how 1/3 in base 10 is a repeating decimal. So you get errors due to rounding. This is also why it's
by tiffanyh 4y ago
TL;DR;
0.1 in binary, is a repeating decimal - just like how 1/3 in base 10 is a repeating decimal.
So you get errors due to rounding.
This is also why it's super important in loops to never use "=" as a condition statement, but instead use "<=" (or ">="). Otherwise you might create an infinite loop.
- MuffinFlavored 4y agohttps://docs.rs/rust_decimal/latest/rust_decimal/ https://docs.rs/rust_decimal/latest/rust_decimal/ Or something like this?
- jacobsenscott 4y agoThe choice of decimal vs float depends on domain. For financial calculations you want to be able to represent amounts exactly. Decimal can represent $1.01 exactly, but float cannot (it picks a value very close to that, and as you do calculations eventually these small inaccuracies amount to real money). But if you are storing the weight of a product a float might be fine - you don't really care if the system thinks you have 50.000001 pounds of product when you have 50 pounds (because your scale isn't that accurate anyway). Floats will generally give you better performance than decimal types as well.
- MuffinFlavored 4y agoWould you say it's "odd" that popular languages (C#, Java, JavaScript/node.js/TypeScript, Python) don't have built in decimal libraries?
- MichaelNolan 4y agoJava has BigDecimal. Python has a decimal and a fraction class. I’m assuming C# has something apart of their standard library as well. And JS/TS has third party libraries that can for arbitrary length precision math as well.
- MuffinFlavored 4y agoThank you. I had a feeling I was wrong. So just JavaScript has BigInt/BigDecimal https://stackoverflow.com/questions/16742578/bigdecimal-in-javascript https://stackoverflow.com/questions/16742578/bigdecimal-in-j..., interesting
- int_19h 4y agoC# has it as part of the language itself, with keyword for the type and a special literal syntax for it: decimal n = 123.456m;
- jacobsenscott 4y agoI don't think I would say it is odd because it isn't a type of number that is directly supported by the hardware. That said it is available in the standard library of most popular languages, and probably just a package install away for any other languages. Also, a plain integer is usually sufficient for financial calculations (just count pennies, not dollars) so in some ways I think decimal types are overused when an integer would do just fine.
- int_19h 4y agoThing is, the practical cases where you want to represent amounts exactly all involve decimals, not binary. If you default to decimals, and someone unknowingly uses them in a situation where binary floats would be better, they still get results they expected, just slower. But if you default to floats, and someone unknowingly uses them in a situation where an exact decimal amount is needed, it can actually produce incorrect (in the sense defined by the functional spec) results. Defaults should be safe, and performance optimizations that are more likely to affect correctness should be opt-in.
- hedora 4y agoIt is also sometimes useful to write abs(x-y) < epsilon.
- tragomaskhalos 4y agoA caveat here is that a good value for epsilon is dependent on the magnitude of the value you're abs'ing.
- bobleeswagger 4y ago> super important in loops to never use "=" as a condition statement, but instead use "<=" (or ">="). Otherwise you might create an infinite loop. Never seems a bit strong, it depends on the context. You can use = on int types all day.
- creeble 4y agoBut never with floating point. I think that's the context of the whole article, and should really be the main take-home (which I'm not sure the article gets across clearly enough).
- TheRealPomax 4y agoyou can use it with floats just fine if your condition boundary is a "whole number float", like running from 0.0 to 1.0 in steps of "some small increment". It's only when your boundary has a non-zero fraction that you're going to have to be more careful.
- creeble 4y ago>running from 0.0 to 1.0 in steps of "some small increment". I'm not sure what you mean; those aren't integers (if that's what you mean by "whole number float"): python3 >>> 0.4 == 0.6 - 0.2 False (edit: formatting for python)
- TheRealPomax 4y agofair, that was completely the wrong example.
- insane_dreamer 4y agoThis is the first clear and concise explanation I've read about why a number as "simple" as 0.1 is imprecise as a float. Thanks!