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

Parsing subnormal float with too many sig figs returns zero, even if it is larger than smallest subnormal #83

Closed
n8xm opened this issue Jul 18, 2021 · 1 comment · Fixed by #92

Comments

@n8xm
Copy link

n8xm commented Jul 18, 2021

I use Base.parse, I get different results than if I use Parsers.parse:

julia> parse(Float64,"9.3494547075363499E-311")
9.3494547075363e-311

julia> parse(Float64,"9.349454707536349E-311")
9.3494547075363e-311

julia> using Parsers

julia> Parsers.parse(Float64,"9.3494547075363499E-311")
0.0

julia> Parsers.parse(Float64,"9.349454707536349E-311")
9.3494547075363e-311

I believe what is happening is that:

  1. We are dealing with subnormal floats
  2. If the subnormal float has "too many" sig figs

It is my understanding that subnormal floats sacrifice precision in order to allow representations that are "close" to zero. However, because 9.3494547075363499E-311 is larger than the smallest subnormal float, the behavior of Base.parse is what I would expect. I would only expect a parser to return 0.0 if the number being parsed is smaller than the smallest subnormal float.

By the way, Python's built-in parser behaves like Base.parse and not Parsers.parse. Using Python 3.9.6:

>>> float("9.3494547075363499E-311")
9.3494547075363e-311
>>> float("9.349454707536349E-311")
9.3494547075363e-311

Similarly, C's atof behaves like Base.parse and not Parsers.parse:

printf("%e\n", atof("9.3494547075363499E-311"));
printf("%e\n", atof("9.349454707536349E-311"));

The above C source produces the output:

9.349455e-311
9.349455e-311

Is there a good reason why Parsers.parse behaves differently from Base.parse in this case?

quinnj added a commit that referenced this issue Oct 14, 2021
Fixes #83. Previously, we eagerly bailed for small enough exponents when
parsing. Instead, we can take a slightly slower path by falling back on
BigInt/BigFloat for however small the exponent is to do the correct
scaling.
@quinnj
Copy link
Member

quinnj commented Oct 14, 2021

Sorry for the slow fix here; a PR is up that should make subnormal parsing more robust: #92

quinnj added a commit that referenced this issue Oct 14, 2021
Fixes #83. Previously, we eagerly bailed for small enough exponents when
parsing. Instead, we can take a slightly slower path by falling back on
BigInt/BigFloat for however small the exponent is to do the correct
scaling.
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

Successfully merging a pull request may close this issue.

2 participants