# 0.1 + 0.2 = 0.30000000000000004 a cliche question

**URL:** <https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695>\
**Category:** language design\
**Created:** [May 13, 2021, 4:14am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695 "2021-05-13T04:14:45Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![carnot-engine](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/carnot-engine/32/6897_2.png) [@carnot-engine](https://internals.rust-lang.org/u/carnot-engine)\
**Post date:** [May 13, 2021, 4:14am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/1 "2021-05-13T04:14:45Z")

</div>

`0.1 + 0.2 = 0.30000000000000004`

i know this is a cliche question

i first see some you tube videos discussing the floating point problem in java-script then i try this on rust

| language | syntax | output |
| --- | --- | --- |
| Rust | println!(0.1+0.2); | 0.30000000000000004 |

i also find same problem

then i try bunch of other programming language like

| language | syntax | output |
| --- | --- | --- |
| python3 | print(0.1+0.2) | 0.30000000000000004 |
| java script | console.log(0.1+0.2); | 0.30000000000000004 |
| node js | console.log(0.1+0.2); | 0.30000000000000004 |
| deno js | console.log(0.1+0.2); | 0.30000000000000004 |
| Kotlin | println(0.1+0.2) | 0.30000000000000004 |
| java | System.out.println(0.1+0.2); | 0.30000000000000004 |
| ruby | puts 0.1+0.2 | 0.30000000000000004 |
| swift | print(0.1+0.2) | 0.30000000000000004 |
| elixir | IO.puts(0.1+0.2) | 0.30000000000000004 |
| julia | 0.1+0.2 | 0.30000000000000004 |

i just google it to find the reason for this problem most of them are discussing about iEEE standards

i know this is not a big problem since we are not sending rocket to space but can any one explain why this is happening

but when i use go lang i got output 0.3

| language | syntax | output |
| --- | --- | --- |
| go | fmt.Println(0.1+0.2) | 0.3 |
| c# | Console.WriteLine(0.1+0.2); | 0.3 |
| r lang | print(0.2+0.1) | 0.3 |
| lua | print(0.1+0.2) | 0.3 |
| C++ | std::cout \<\< 0.1+0.2; | 0.3 |
| C | printf("%f",0.1+0.2); | 0.300000 |

NOTE: i use [replit.com](http://replit.com) for running the program [https://replit.com/languages](https://replit.com/languages)

| no | qn |
| --- | --- |
| 0 | whether this language really solve the floating point problem or just do some tweaking in background |
| 1 | is this because it is using good garbage collector algorithms that clear the buffer |
| 2 | are they just round the output |
| 3 | are they using good floating point algorithms |
| 4 | why only some programming language are slowing this problem |
| 5 | is this problem is due to design of programming language |
| 6 | how to solve this problem in rust language |

can any one give a convincing answer

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mbrubeck/32/174_2.png) [@mbrubeck](https://internals.rust-lang.org/u/mbrubeck)\
**Post date:** [May 13, 2021, 4:41am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/2 "2021-05-13T04:41:22Z")

</div>

Languages like Go that print "0.3" are rounding the output.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [May 13, 2021, 5:23am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/3 "2021-05-13T05:23:30Z")

</div>

Use [Float Toy](https://evanw.github.io/float-toy/) to look at the representations of the numbers in the different IEEE formats. You'll see that `0.30000000000000004` is the correct answer.

---

<div class="post-metadata">

**Author:** ![hyeonu](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hyeonu/32/2162_2.png) [@hyeonu](https://internals.rust-lang.org/u/hyeonu)\
**Post date:** [May 13, 2021, 6:45am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/4 "2021-05-13T06:45:26Z")

</div>

And the `"0.3"` means you can't round trip the float -\> string -\> float.

[https://play.golang.org/p/\_hNWoypcMDx](https://play.golang.org/p/_hNWoypcMDx)

[https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=17985a96d04373fe348a5fe2282b1575](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=17985a96d04373fe348a5fe2282b1575)

---

<div class="post-metadata">

**Author:** ![hyeonu](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hyeonu/32/2162_2.png) [@hyeonu](https://internals.rust-lang.org/u/hyeonu)\
**Post date:** [May 13, 2021, 6:56am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/5 "2021-05-13T06:56:53Z")

</div>

Also the NASA answered that `#define PI 3.141592653589793` is enough for interplanetary navigation.

> **[How Many Decimals of Pi Do We Really Need? - Edu News | NASA/JPL Edu](https://www.jpl.nasa.gov/edu/news/2016/3/16/how-many-decimals-of-pi-do-we-really-need/)**
>
> Earlier this week, we received this question from a fan on Facebook who wondered how many decimals of the mathematical constant pi (π) NASA-JPL scientists and engineers use when making calculations:Does JPL only use 3.14 for its pi calculations? Or...

---

<div class="post-metadata">

**Author:** ![hyeonu](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hyeonu/32/2162_2.png) [@hyeonu](https://internals.rust-lang.org/u/hyeonu)\
**Post date:** [May 13, 2021, 10:37am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/7 "2021-05-13T10:37:34Z")

</div>

Can you please specify what actually is the problem you found? Within the IEEE754 double precision floating point 0.1 + 0.2 is 0.30000000000000004 by specification. And some languages decided to not be very precise on printing them so they just round it into shorter representation. To me all these are just facts and can't see any problem, but different person may find different problems from same facts.

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [May 13, 2021, 11:14am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/8 "2021-05-13T11:14:37Z")

</div>

```rust
println!("{:.1}", 0.1+0.2);

```

This prints `0.3`

The problem with this approach however is that specifying a bigger precision keeps the trailing zeroes:

```rust
println!("{:.5}", 0.1+0.2);

```

This prints `0.30000`

---

<div class="post-metadata">

**Author:** ![nacaclanga](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nacaclanga/32/7461_2.png) [@nacaclanga](https://internals.rust-lang.org/u/nacaclanga)\
**Post date:** [May 13, 2021, 12:43pm UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/9 "2021-05-13T12:43:00Z")

</div>

This mainly relates to the fact that 0.1f64+0.2f64!=0.3f64. See e.g. [Basic usage - Documentation for float\_eq 0.6.0](https://jtempest.github.io/float_eq-rs/book/tutorials/basic_usage.html). My guess is that Rust println! (and a couple of other languages) uses a more modern algorithm, that maps every floating point number to one string representation in such a manner that the exact f64 binary representation can be reconstructed. Because 0.1f64+0.2f64 simply isn't the closesed f64 number to 0.3, it is mapped to `0.30000000000000004`. Some of the other languages might use a different printing strategy (such as only printing the first 6 digitis or consider e.g. 5 zeros to be an finishing criteria.)

---

<div class="post-metadata">

**Author:** ![zackw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zackw/32/2071_2.png) [@zackw](https://internals.rust-lang.org/u/zackw)\
**Post date:** [May 13, 2021, 1:15pm UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/10 "2021-05-13T13:15:42Z")

</div>

> [@carnot-engine](#):
>
> 1. how to solve this problem in rust language

I think you may be looking for the [decimal](https://crates.io/crates/decimal) crate.

---

<div class="post-metadata">

**Author:** ![ckaran](https://avatars.discourse-cdn.com/v4/letter/c/f475e1/32.png) [@ckaran](https://internals.rust-lang.org/u/ckaran)\
**Post date:** [May 13, 2021, 1:50pm UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/11 "2021-05-13T13:50:20Z")

</div>

1. Floating point numbers are the tools of the devil, invented solely to drive good programmers insane.
2. Like @zackw said, if you need precision, use a crate that offers it for you, e.g., [rug](https://crates.io/crates/rug) or [ramp](https://crates.io/crates/ramp), or any of the other ones that are out there.

---

<div class="post-metadata">

**Author:** ![mjbshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjbshaw/32/5103_2.png) [@mjbshaw](https://internals.rust-lang.org/u/mjbshaw)\
**Post date:** [May 13, 2021, 1:51pm UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/12 "2021-05-13T13:51:43Z")

</div>

Should this be on [users.rust-lang.org](http://users.rust-lang.org)?

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [May 13, 2021, 2:11pm UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/13 "2021-05-13T14:11:33Z")

</div>

In **all** of these languages the actual value in memory is exactly `0.30000000000000004`, because that's the native representational of the number on the CPU (all CPUs these days have settled on using the same standard for floats).

Some of these languages choose to round the value down when printing it, so they display what you want to see, but not what the value really is.

Try printing `(0.1 + 0.2) * 1e17` and you'll see that all of them display the same integer.

[https://0.30000000000000004.com](https://0.30000000000000004.com)

---

<div class="post-metadata">

**Author:** ![ZyX-I](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zyx-i/32/11398_2.png) [@ZyX-I](https://internals.rust-lang.org/u/ZyX-I)\
**Post date:** [May 13, 2021, 11:11pm UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/14 "2021-05-13T23:11:31Z")

</div>

Go is doing something weird here:

```rust
package main
import ( "fmt" )
func main() { fmt.Printf("%.30g", 0.1 + 0.2); }

```

[yields](https://play.golang.org/p/f_ciCYbcQfj) 0.299999999999999988897769753748 there. This is actually closer to 0.3. As a wild guess this may be a result of something like constant folding with compiler using better precision internally.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [May 13, 2021, 11:22pm UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/15 "2021-05-13T23:22:46Z")

</div>

> [@ZyX-I](#):
>
> As a wild guess this may be a result of something like constant folding with compiler using better precision internally.

Apparently the website that @kornel linked has [the answer](https://0.30000000000000004.com/#go):

> ### Go
> 
> ```go
> package main
> import "fmt"
> 
> func main() {
> fmt.Println(.1 + .2)
> var a float64 = .1
> var b float64 = .2
> fmt.Println(a + b)
> fmt.Printf("%.54f\n", .1 + .2)
> }
> 
> ```
> 
> ```plaintext
> 0.3  
> 0.30000000000000004  
> 0.299999999999999988897769753748434595763683319091796875
> 
> ```
> 
> Go numeric constants [have arbitrary precision](http://blog.golang.org/constants#TOC_8.).

---

<div class="post-metadata">

**Author:** ![davisp](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/davisp/32/8157_2.png) [@davisp](https://internals.rust-lang.org/u/davisp)\
**Post date:** [May 20, 2021, 5:32pm UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/16 "2021-05-20T17:32:27Z")

</div>

They way I like to explain this is to start by pointing out that there are a finite set of double precision floating point numbers. Given 8 bytes there can't be more than `2^64` different values (in reality it's slightly less than this given not all combinations of bits are valid floating point values).

Given that observation, when we parse a base 10 string representation of a number (e.g., `0.1`, `0.2`, or `0.3`) what we're actually doing is just finding the closest valid floating point value. The thing to keep in mind here is that we can write out two base 10 values that are so close that they are represented by the same exact binary representation in memory. For instance, any number between `1.0` and `1.0 + f64::EPSILON` will pick the same internal representation.

The reason this is interesting for the current discussion is that when we go the opposite route and convert from a floating point value to a string there are an infinite number of strings we could return so long as they all end up parsing to the same floating point value. The "old school" way of printing a floating point value that could be parsed back into the same exact floating point value would be to just `printf("%0.64f\n", val)` which includes enough digits after the decimal place to make this guarantee.

While that works, most folks don't like having to deal with `0.1000000000000000055511151231257827021181583404541015625000000000` when they just wanted `0.1`. So the question then becomes, "What's the shortest string I can return that will parse to the given floating point value?". Unsurprisingly, it turns out that this is actually fairly complicated stuff. [`dtoa.c`](http://www.netlib.org/fp/dtoa.c) is the canonical implementation if you're interested.

The last step in understanding why `0.1 + 0.2` doesn't print as `0.3` is to consider the process that is happening. First we pick floating point representations for `0.1` and `0.2` and then add them according to floating point math rules. This gives us the floating point value in hex as `0x3FD3333333333334`. However, when we parse `0.3` directly we get `0x3FD3333333333333` which is very close but not the same (N.B., there's no valid floating point value between these two values as they are "one apart").

So when we print the result of `0.1 + 0.2` we show `0.30000000000000004` because it is the shortest possible string that can be parsed into the same exact floating point value. Returning `0.3` would have parsed into a different floating point value so that would be invalid.

So the general answer is that any language that shows `0.30000000000000004` is showing a very precise representation of the floating point value in RAM. Any language that shows fewer digits than `0.30000000000000004` is showing a rounded and/or truncated representation.

| no | qn |
| --- | --- |
| 0 | whether this language really solve the floating point problem or just do some tweaking in background |
| | Assuming "this language" refers to Rust, its because Rust is giving you a string that represents a specific double precision floating point value. If by "floating point problem" you mean `0.1 + 0.2 != 0.3`, its not actually a problem as that's properly implemented IEEE-754 behavior. If you wish to avoid this you want to look into [`arbitrary precision arithmetic`](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic) |
| 1 | is this because it is using good garbage collector algorithms that clear the buffer |
| | No. This has nothing to do with garbage collection |
| 2 | are they just round the output |
| | Any language that is showing fewer digits than `0.30000000000000004` is either rounding or truncating the values they are printing. |
| 3 | are they using good floating point algorithms |
| | Any language that is showing fewer digits than `0.30000000000000004` is losing information in the output. Whether losing information subtly is good or not is up to you. |
| 4 | why only some programming language are slowing this problem |
| | Different languages made different decisions on how they render floating point values. |
| 5 | is this problem is due to design of programming language |
| | No, this behavior is due to a correct implementation of IEEE-754 behaviors |
| 6 | how to solve this problem in rust language |
| | I assume you mean "How can I have Rust print 0.3 in this situation?" If that's the case you'll want to either look into arbitrary precision math or round your values to some number of significant digits. See [this example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0345b817c23d1d9b7f14d0ea10db7b78). |

---

<div class="post-metadata">

**Author:** ![Luro02](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/luro02/32/8947_2.png) [@Luro02](https://internals.rust-lang.org/u/Luro02)\
**Post date:** [May 23, 2021, 8:18am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/17 "2021-05-23T08:18:56Z")

</div>

[https://float.exposed](https://float.exposed)

This site is also very nice to toy around with

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [August 21, 2021, 8:19am UTC](https://internals.rust-lang.org/t/0-1-0-2-0-30000000000000004-a-cliche-question/14695/18 "2021-08-21T08:19:50Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
