Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
December 03, 2019 Floating-Point arithmetic in dlang - Difference to other languages | ||||
---|---|---|---|---|
| ||||
Today i have stumbled on Hacker News into: https://0.30000000000000004.com/ I am learning D, that's why i have to ask. Why does writefln("%.17f", .1+.2); not evaluate into: 0.30000000000000004, like C++ but rather to: 0.29999999999999999 Many other languages evaluate to 0.30000000000000004 as well. |
December 03, 2019 Re: Floating-Point arithmetic in dlang - Difference to other languages | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jan Hönig | On Tuesday, 3 December 2019 at 09:22:49 UTC, Jan Hönig wrote: > Today i have stumbled on Hacker News into: https://0.30000000000000004.com/ > > I am learning D, that's why i have to ask. > > Why does > > writefln("%.17f", .1+.2); > > not evaluate into: 0.30000000000000004, like C++ > but rather to: 0.29999999999999999 > > Many other languages evaluate to 0.30000000000000004 as well. You can get this result in D as well: $ rdmd --eval 'double a = .1, b = .2; writefln("%.17f", a+b)' 0.30000000000000004 https://dlang.org/spec/float.html explains it: real (80bit, 'long double' in C) floats are used in your first calculation, and doubles are used in my revised example. Most other languages give you the double result for very reasonable historical reasons, described here: https://retrocomputing.stackexchange.com/questions/9751/did-any-compiler-fully-use-intel-x87-80-bit-floating-point/9760#9760 D's behavior is a minor 'miss': https://nwcpp.org/Oct-2019.html ... I wanted to include a C example that gives the D result, but it seems to be trickier to force 80 bit intermediates. |
December 03, 2019 Re: Floating-Point arithmetic in dlang - Difference to other languages | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jan Hönig | On Tuesday, 3 December 2019 at 09:22:49 UTC, Jan Hönig wrote: > not evaluate into: 0.30000000000000004, like C++ > but rather to: 0.29999999999999999 You get the same in C++ with: #include <cstdio> int main() { printf("%.17f",double(0.1L + 0.2L)); } |
December 03, 2019 Re: Floating-Point arithmetic in dlang - Difference to other languages | ||||
---|---|---|---|---|
| ||||
Posted in reply to mipri | On Tuesday, 3 December 2019 at 09:52:18 UTC, mipri wrote:
> Most other languages give you the double result for very
> reasonable historical reasons
Not only historical, it is also for numerical reasons. You can get very unpredictable results if you do compares and compiletime evalution is different from runtime evaluation.
|
December 03, 2019 Re: Floating-Point arithmetic in dlang - Difference to other languages | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jan Hönig | On Tuesday, 3 December 2019 at 09:22:49 UTC, Jan Hönig wrote:
> Today i have stumbled on Hacker News into: https://0.30000000000000004.com/
>
> I am learning D, that's why i have to ask.
>
> Why does
>
> writefln("%.17f", .1+.2);
>
> not evaluate into: 0.30000000000000004, like C++
> but rather to: 0.29999999999999999
>
> Many other languages evaluate to 0.30000000000000004 as well.
D lang could have a very good sprintf replacement.
|
December 03, 2019 Re: Floating-Point arithmetic in dlang - Difference to other languages | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jan Hönig | On Tue, Dec 03, 2019 at 09:22:49AM +0000, Jan Hönig via Digitalmars-d-learn wrote: > Today i have stumbled on Hacker News into: https://0.30000000000000004.com/ > > I am learning D, that's why i have to ask. > > Why does > > writefln("%.17f", .1+.2); > > not evaluate into: 0.30000000000000004, like C++ > but rather to: 0.29999999999999999 > > Many other languages evaluate to 0.30000000000000004 as well. In short, because they use 64-bit floats for intermediate values (`double`), whereas D defaults to 80-bit intermediates (`real`). The use of a more precise intermediate value is also indicated by the fact that 0.29999999999999999 is closer to the real answer (error of 1e-17) than 0.30000000000000004 (error of 4e-17). If you explicitly specify to use `double`, then you should get the same answer as C++. double a=.1, b=.2; writefln("%.17f", a+b); T -- MSDOS = MicroSoft's Denial Of Service |
Copyright © 1999-2021 by the D Language Foundation