Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exact result of 2^20 + 2^-20 #174

Closed
mohamed-180 opened this issue Jul 19, 2023 · 1 comment
Closed

Exact result of 2^20 + 2^-20 #174

mohamed-180 opened this issue Jul 19, 2023 · 1 comment

Comments

@mohamed-180
Copy link

Based on How can I get the exact result of 10^20 + 10^-20 in Python? , I have tried this

using DecFP
using Printf
a = Dec128(10)^20
b = Dec128(10)^-20

@sprintf("%.20f", a + b)
# > "100000000000000000000.000000000000000000000"

where it must be "100000000000000000000.00000000000000000001"

Note that

@sprintf("%.20f", b)

#> "0.00000000000000000001"

Why a + b miss the fraction.

Regards;

@stevengj
Copy link
Member

Dec128 corresponds to 34 significant digits in decimal:

julia> precision(Dec128, base=10)
34

Adding 10^-20 to 10^20 would require 41 significant digits. As a result, the 20th decimal place in the result gets rounded off to 0.

This is fundamental to how floating-point arithmetic, of any type, works — only ever have a finite number of significant digits.

To get 10^20 + 10^-20 exactly, you'd need to use a type with even more precision (more digits) than Dec128. You could use an arbitrary precision type like Julia's built-in BigFloat type:

julia> setprecision(100, base=10); # use roughly 100 decimal digits

julia> big"1e20" + big"1e-20"
1.00000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000003e+20

Even this is not quite exact — see the 3 in the 80th digit — because BigFloat is a "binary" floating-point type, which represents integers times powers of 2 exactly (up to some number of binary digits), but not integers times powers of 10, so 1e-20 needs to be rounded to represent it as the nearest BigFloat. To do this operation exactly you'd need a high-precision decimal floating-point type, e.g. Decimals.jl.

See also PSA: Floating-point arithmetic on the Julia discussion board.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants