TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

0.30000000000000004

768 pointsby beznetover 5 years ago

45 comments

mcvover 5 years ago
The big issue here is what you&#x27;re going to use your numbers for. If you&#x27;re going to do a lot of fast floating point operations for something like graphics or neural networks, these errors are fine. Speed is more important than exact accuracy.<p>If you&#x27;re handling money, or numbers representing some other real, important concern where accuracy matters, most likely any number you intend to show to the user as a number, floats are not what you need.<p>Back when I started using Groovy, I was very pleased to discover that Groovy&#x27;s default decimal number literal was translated to a BigDecimal rather than a float. For any sort of website, 9 times out of 10, that&#x27;s what you need.<p>I&#x27;d really appreciate it if Javascript had a native decimal number type like that.
评论 #21687118 未加载
评论 #21690589 未加载
评论 #21691749 未加载
评论 #21690538 未加载
评论 #21690513 未加载
评论 #21691518 未加载
评论 #21687323 未加载
评论 #21687891 未加载
评论 #21690363 未加载
dspillettover 5 years ago
MS Excel tries to be clever and disguise the most common places this is noticed.<p>Give it =0.1+0.2-0.3 and it will see what you are trying to do and return 0.<p>Give it anything slightly more complicated such as =(0.1+0.2-0.3) and this won&#x27;t trip, in this example displaying 5.55112E-17 or similar.
评论 #21688626 未加载
评论 #21696007 未加载
_bxg1over 5 years ago
I remember in college when we learned about this and I had the thought, &quot;Why don&#x27;t we just store the numerator and denominator?&quot;, and threw together a little C++ class complete with (then novel, to me) operator-overloads, which implemented the concept. I felt very proud of myself. Then years later I learned that it&#x27;s a thing people actually use: <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rational_data_type" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rational_data_type</a>
评论 #21687410 未加载
评论 #21687018 未加载
评论 #21686744 未加载
评论 #21686763 未加载
评论 #21686817 未加载
评论 #21689266 未加载
评论 #21687798 未加载
评论 #21687614 未加载
评论 #21689451 未加载
评论 #21688424 未加载
评论 #21687284 未加载
dangover 5 years ago
A thread from 2017.00000000000: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=14018450" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=14018450</a><p>2015.000000000000: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=10558871" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=10558871</a>
评论 #21687202 未加载
评论 #21689229 未加载
mark-rover 5 years ago
Also the subject of one of the most popular questions on StackOverflow: <a href="https:&#x2F;&#x2F;stackoverflow.com&#x2F;q&#x2F;588004&#x2F;5987" rel="nofollow">https:&#x2F;&#x2F;stackoverflow.com&#x2F;q&#x2F;588004&#x2F;5987</a>
lordnachoover 5 years ago
While it&#x27;s true that floating point has its limitations, this stuff about not using it for money seems overblown to me. I&#x27;ve worked in finance for many years, and it really doesn&#x27;t matter that much. There are de minimis clauses in contracts that basically say &quot;forget about the fractions of a cent&quot;. Of course it might still trip up your position checking code, but that&#x27;s easily fixed with a tiny tolerance.
评论 #21688398 未加载
GuB-42over 5 years ago
That&#x27;s one of the worst domain name ever. When the topic comes along, I always remember about &quot;that single-serving website with a domain name that looks like a number&quot; and then take a surprisingly long time searching for it.<p>I have written a test framework and I am quite familiar with these problems, and comparing floating point numbers is a PITA. I had users complaining that 0.3 is not 0.3.<p>The code managing these comparisons turned out to be more complex than expected. The idea is that values are represented as ranges, so, for example, the IEEE-754 &quot;0.3&quot; is represented as ]0.299~, 0.300~[ which makes it equal to a true 0.3, because 0.3 is within that range.
评论 #21687635 未加载
评论 #21689677 未加载
评论 #21687379 未加载
评论 #21691455 未加载
评论 #21687508 未加载
评论 #21688544 未加载
评论 #21687382 未加载
mc3over 5 years ago
This is a good thing to be aware of.<p>Also the &quot;field&quot; of floating point numbers is not commutative†, (can run on JS console:)<p>x=0;for (let i=0; i&lt;10000; i++) { x+=0.0000000000000000001; }; x+=1<p>--&gt; 1.000000000000001<p>x=1;for (let i=0; i&lt;10000; i++) { x+=0.0000000000000000001; };<p>--&gt; 1<p>Although most of the time a+b===b+a can be relied on. And for most of the stuff we do on the web it&#x27;s fine!††<p>† edit: Please s&#x2F;commutative&#x2F;associative&#x2F;, thanks for the comments below.<p>†† edit: that&#x27;s wrong! Replace with (a+b)+c === a+(b+c)
评论 #21686761 未加载
评论 #21686660 未加载
评论 #21686775 未加载
评论 #21686837 未加载
评论 #21686640 未加载
maxdamantusover 5 years ago
I feel like it should really be emphasised that the reason this occurs is due to a mismatch between binary exponentiation and decimal exponentiation.<p><i>0.1 = 1 × 10^-1</i>, but there is no integer significand <i>s</i> and integer exponent <i>e</i> such that <i>0.1 = s × 2^e</i>.<p>When this issue comes up, people seem to often talk about fixing it by using decimal floats or fixed-point numbers (using some <i>10^x</i> divisor). If you change the base, you solve the problem of representing <i>0.1</i>, but whatever base you choose, you&#x27;re going to have unrepresentable rationals. Base 2 fails to represent <i>1&#x2F;10</i> just as base 10 fails to represent <i>1&#x2F;3</i>. All you&#x27;re doing by using something based around the number <i>10</i> is supporting numbers that we expect to be able to write on paper, not solving some fundamental issue of number representation.<p>Also, binary-coded decimal is irrelevant. The thing you&#x27;re wanting to change is <i>which</i> base is used, not how any integers are represented in memory.
评论 #21689150 未加载
评论 #21688823 未加载
ufoover 5 years ago
One small tip about printf for floating point numbers. In addition to &quot;%f&quot;, you can also print them using &quot;%g&quot;. While the precision specifier in %f refers to digits after the decimal period, in %g the precision refers to the number of significant digits. The %g version is also allowed to use exponential notation, which often results in more pleasant-looking output than %f.<p><pre><code> printf(&quot;%.4g&quot;, 1.125e10) --&gt; 1.125e+10 printf(&quot;%.4f&quot;, 1.125e10) --&gt; 11250000000.0000</code></pre>
评论 #21686922 未加载
amyjessover 5 years ago
One of my favorite things about Perl 6 is that decimal-looking literals are stored as rationals. If you actually want a float, you have to use scientific notation.<p>Edit: Oh wait, it&#x27;s listed in the main article under Raku. Forgot about the name change.
lelfover 5 years ago
That’s only formatting.<p>The other (and more important) matter, — that is not even mentioned, — is comparison. E. g. in “rational by default in this specific case” languages (Perl 6),<p><pre><code> &gt; 0.1+0.2==0.3 True </code></pre> Or, APL (now they are floats there! But comparison is special)<p><pre><code> 0.1+0.2 0.3 ⎕PP←20 ⋄ 0.1+0.2 0.30000000000000004 (0.1+0.2) ≡ 0.3 1</code></pre>
评论 #21745329 未加载
评论 #21686948 未加载
DonHopkinsover 5 years ago
The runner up for length is FORTRAN with: 0.300000000000000000000000000000000039<p>And the length (but not value) winner is GO with: 0.299999999999999988897769753748434595763683319091796875
评论 #21688323 未加载
jonny_ehover 5 years ago
&gt; It&#x27;s actually pretty simple<p>The explanation then goes on to be very complex. e.g. &quot;it can only express fractions that use a prime factor of the base&quot;.<p>Please don&#x27;t say things like this when explaining things to people, it makes them feel stupid if it doesn&#x27;t click with the first explanation.<p>I suggest instead &quot;It&#x27;s actually rather interesting&quot;.
评论 #21687126 未加载
评论 #21686975 未加载
评论 #21687054 未加载
评论 #21686877 未加载
评论 #21687261 未加载
评论 #21687225 未加载
评论 #21687031 未加载
评论 #21686989 未加载
评论 #21687453 未加载
garyclarke27over 5 years ago
Postgresql figured this out many years ago with their Decimal&#x2F;Numeric type. It can handle any size number and it performs fractional arithmetic perfectly accurately - how amazingly for the 21st Century! Is comically tragic to me that all of the mainstream programming languages are still so far behind, so primitive that they do not have a native accurate number type that can handle fractions.
评论 #21691083 未加载
Ididntdothisover 5 years ago
I still remember when I encountered this and nobody else in the office knew about it either. We speculated about broken CPUs and compilers until somebody found a newsgroup post that explained everything. Makes me wonder why we haven&#x27;t switched to a better floating point model in the last decades. It will probably be slower but a lot of problems could be avoided.
评论 #21686769 未加载
评论 #21686783 未加载
评论 #21686907 未加载
评论 #21686681 未加载
评论 #21686850 未加载
评论 #21686675 未加载
评论 #21686942 未加载
评论 #21686652 未加载
评论 #21686807 未加载
评论 #21686712 未加载
combatentropyover 5 years ago
In JavaScript, you could use a library like decimal.js. For simple situations, could you not just convert the final result to a precision of 15 or less?<p><pre><code> &gt; 0.1 + 0.2; &lt; 0.30000000000000004 &gt; (0.1 + 0.2).toPrecision(15); &lt; &quot;0.300000000000000&quot; </code></pre> From Wikipedia: &quot;If a decimal string with at most 15 significant digits is converted to IEEE 754 double-precision representation, and then converted back to a decimal string with the same number of digits, the final result should match the original string.&quot; --- <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Double-precision_floating-point_format" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Double-precision_floating-poin...</a>
ChuckMcMover 5 years ago
That is why I only used base 2310 for my floating point numbers :-). FWIW there are some really interesting decimal format floating point libraries out there (see <a href="http:&#x2F;&#x2F;speleotrove.com&#x2F;decimal&#x2F;" rel="nofollow">http:&#x2F;&#x2F;speleotrove.com&#x2F;decimal&#x2F;</a> and <a href="https:&#x2F;&#x2F;github.com&#x2F;MARTIMM&#x2F;Decimal" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;MARTIMM&#x2F;Decimal</a>) and the early computers had decimal as a native type (<a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Decimal_computer#Early_computers" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Decimal_computer#Early_compute...</a>)
评论 #21687315 未加载
skohanover 5 years ago
This is part of the reason Swift Numerics is helping to make it much nicer to do numerical computing in Swift.<p><a href="https:&#x2F;&#x2F;swift.org&#x2F;blog&#x2F;numerics&#x2F;" rel="nofollow">https:&#x2F;&#x2F;swift.org&#x2F;blog&#x2F;numerics&#x2F;</a>
评论 #21687780 未加载
评论 #21687306 未加载
gowldover 5 years ago
This is a great shibboleth for identifying mature programmers who understand the complexity of computers, vs arrogant people who wonder aloud how systems developers and language designers could get such a &quot;simple&quot; thing wrong.
评论 #21687159 未加载
dunhamover 5 years ago
Interesting, I searched for &quot;1.2-1.0&quot; on google. The calculator comes up and it briefly flashes 0.19999999999999996 (and no calculator buttons) before changing to 0.2. This happens inconsistently on reload.
YeGoblynQueenneover 5 years ago
Swi-Prolog (listed int he article) also supports rationals:<p><pre><code> ?- A is rationalize(0.1 + 0.2), format(&#x27;~50f~n&#x27;, [A]). 0.30000000000000000000000000000000000000000000000000 A = 3 rdiv 10.</code></pre>
okennedyover 5 years ago
This specific issue nearly drove me insane trying to debug a SQL -&gt; C++&#x2F;Scala&#x2F;OCaml transpiler years ago. We were using the TPC-H benchmark as part of our test suite, and (unbeknownst to me), the validation parameters for one of the queries (Q6) triggered this behavior (0.6+0.1 != 0.7), but only in the C&#x2F;Scala targets. OCaml (around which we had built most of our debugging infrastructure) handled the math correctly...<p>Fun times.
goosehonkover 5 years ago
When did RFC1035 get thrown under the bus? According to it, with respect to domain name labels, &quot;They must start with a letter&quot; (2.3.1).
评论 #21686799 未加载
评论 #21695970 未加载
评论 #21686760 未加载
评论 #21686688 未加载
dec0dedab0deover 5 years ago
I wish high level languages (specifically python) would default to using decimal, and only use a float when cast specifically. From what I understand that would make things slower, but as a higher level language you&#x27;re already making the trade of running things slower to be easier to understand.<p>That said, it&#x27;s one of my favorite trivia gotchas.
mytailorisrichover 5 years ago
Fixed-point calculations seem to be somewhat of a lost art these days.<p>It used to be widespread because floating point processors were rare and any floating point computation was costly.<p>That&#x27;s not longer the case and everyone seems to immediately use floating point arithmetic without being fully aware of the limitations and&#x2F;or without considering the precision needed.
qwerty456127over 5 years ago
As soon as I&#x27;ve started developing real-life business apps I&#x27;ve started to dream about a POWER which is said to have hardware decimal type support. Javs&#x27;s BigDecimal solves the problem on x86 but it is at least an order of magnitude more slow than FPU-accelerated types.
评论 #21691583 未加载
povikover 5 years ago
In the Go example, can someone explain the difference between the first and the last case?
评论 #21688047 未加载
tus88over 5 years ago
Mods: Can we have a top level menu option called &quot;Floating point explained&quot;?
gumbyover 5 years ago
Not surprisingly Common Lisp gets it right. I don’t mean this is snark (I don’t mean to imply you are a weenie if you don’t use lisp) but just to show that it picked a different kind of region in the language design domain.
thanatropismover 5 years ago
Computer languages should default to fixed precision decimals and offer floats with special syntax (eg “0.1f32”).<p>The status quo is that even Excel defaults to floats and wrong calculations with dollars and cents are widespread.
Waterluvianover 5 years ago
The thing that surprised me the most (because I never learned any of this in school) was not just the lack of precision to represent some numbers, but that precision falls off a cliff for very large numbers.
alberthover 5 years ago
TL;DR - 0.1 in Base 2 (binary) is the equivalent of 1&#x2F;3 in Base 10 meaning, it’s a repeating decimal that causes rounding issues (0.333333 repeating)<p>This is why you should never do “does X == 0.1” because it might not evaluate accurately
0xDEEPFACover 5 years ago
Whoo go Ada, one of the few to get it right. Must be the goto for secure programming for a reason.<p>Take that Rust and C ; )
评论 #21687907 未加载
bluetwoover 5 years ago
Happy to see ColdFusion doing it right. Also, good for Julia for having the support for fractions.
cogburnd02over 5 years ago
I love how Awk, bc, and dc all DTRT. I wonder what postscript(&#x2F;Ghostscript?) does.
xkriva11over 5 years ago
for Smalltalk, the list is not complete, it has scalled decimals and fractions too: 0.1s + 0.2s = 0.3s . (1&#x2F;10) + (2&#x2F;10) = (3&#x2F;10)
adamcover 5 years ago
Those Babylonians were ahead of their time.
threatofrainover 5 years ago
Use Int types for programming logic.
评论 #21687061 未加载
cellularover 5 years ago
Why is D different than the rest?!
mttpgnover 5 years ago
bc actually computes this correctly, and returns 0.3 for 0.1 + 0.2
idonotknowwhyover 5 years ago
This has been posted here many times before. It even got mocked on n-gate in 2017 <a href="http:&#x2F;&#x2F;n-gate.com&#x2F;hackernews&#x2F;2017&#x2F;04&#x2F;07&#x2F;" rel="nofollow">http:&#x2F;&#x2F;n-gate.com&#x2F;hackernews&#x2F;2017&#x2F;04&#x2F;07&#x2F;</a>
edisonjoaoover 5 years ago
lol what
beckerdoover 5 years ago
Please check some of the online papers on Posit numbers and Unum computing, especially by John Gustafson. In general, Unums can represent more numbers, with less rounding, and fewer exceptions than floating points. Many software and hardware vendors are starting to do interesting work with Posits.
评论 #21692083 未加载
pmarreckover 5 years ago
IEEE floating-point is disgusting. The non-determinism and illusion of accuracy is just wrong.<p>I use integer or fixed-point decimal if at all possible. If the algorithm needs floats, I convert it to work with integer or fixed-point decimal instead. (Or if possible, I see the decimal point as a &quot;rendering concern&quot; and just do the math in integers and leave the view to put the decimal by whatever my selected precision is.)
评论 #21687071 未加载
评论 #21687058 未加载
评论 #21687467 未加载
评论 #21687084 未加载
评论 #21687060 未加载