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

float rounding mode affects integer hash function #8910

Closed
JeffBezanson opened this issue Nov 5, 2014 · 13 comments
Closed

float rounding mode affects integer hash function #8910

JeffBezanson opened this issue Nov 5, 2014 · 13 comments

Comments

@JeffBezanson
Copy link
Member

I found this pretty funny:

julia> set_rounding(Float64, RoundToZero);

ERROR: key not found: :normal
 in write_prompt at ./LineEdit.jl:648
 in refresh_multi_line at LineEdit.jl:203
 in activate at ./LineEdit.jl:1251
 in activate_3B_14357 at /home/jeff/src/julia2/julia/usr/bin/../lib/julia/sys.so
 in transition at ./LineEdit.jl:1273
 in anonymous at REPL.jl:597
 in run_interface at ./LineEdit.jl:1329
 in run_interface_3B_14372 at /home/jeff/src/julia2/julia/usr/bin/../lib/julia/sys.so
 in run_frontend at ./REPL.jl:825
 in run_repl at ./REPL.jl:170
 in _start at ./client.jl:420
 in _start_3B_14249 at /home/jeff/src/julia2/julia/usr/bin/../lib/julia/sys.so

[jeff ~/src/julia/base]$ 

Naturally, due to this:

hash(x::Uint64,  h::Uint) = hx(x, float64(x), h)

Maybe in the float64(x) conversion we should mask out the low bits of x to make it independent of rounding mode?

@eschnett
Copy link
Contributor

eschnett commented Nov 6, 2014

The low bits of x probably carry more entropy than the high bits. Why not mask out the 22 highest bits? This way, x can always be represented as float64.

@JeffBezanson
Copy link
Member Author

Yes, we could do that too. It won't matter so much because the hash function ends up using all bits of the integer anyway.

@StefanKarpinski
Copy link
Member

You can create examples where rounding affects all the bits, so this doesn't seem like a solution.

@JeffBezanson
Copy link
Member Author

If x is reduced to a 52-bit integer the conversion is exact, isn't it?

@StefanKarpinski
Copy link
Member

Perhaps your example is incomplete – when I do the same thing, no error occurs. So it's a bit hard to tell what exactly the issue is that you're talking about here.

@JeffBezanson
Copy link
Member Author

Hmm, that's interesting. Try this:

julia> with_rounding(Float64, RoundToZero) do
        hash(:normal, Uint(0))
       end
0xfaf37cd4f0c6cde6

julia> hash(:normal, Uint(0))
0xbea927fdf832243d

@StefanKarpinski
Copy link
Member

These give the same hash for me:

julia> with_rounding(Float64, RoundToZero) do
               hash(:normal, Uint(0))
              end
0xfaf37cd4f0c6cde6

julia> hash(:normal, Uint(0))
0xfaf37cd4f0c6cde6

@JeffBezanson
Copy link
Member Author

Try a different rounding mode?

@JeffBezanson
Copy link
Member Author

More data:

julia> x = 0xfaf37cd4f0c6cde6;

julia> with_rounding(Float64,RoundToZero) do
        float64(x)
       end
1.8082934182837144e19

julia> float64(x)
1.8082934182837146e19

@StefanKarpinski
Copy link
Member

It's pretty jarring that this depends on floating-point rounding modes. I really think that the whole rounding mode business is completely unusable.

julia> with_rounding(Float64, RoundNearest) do
               hash(:normal, Uint(0))
              end
0xbea927fdf832243d

julia> with_rounding(Float64, RoundDown) do
               hash(:normal, Uint(0))
              end
0xfaf37cd4f0c6cde6

julia> with_rounding(Float64, RoundUp) do
               hash(:normal, Uint(0))
              end
0xbea927fdf832243d

@JeffBezanson
Copy link
Member Author

What do you mean by "this"? The hash function? That's the whole point of this issue.

Interestingly it looks like you were somehow already in RoundDown or RoundToZero mode. I wonder if some library set that?

@StefanKarpinski
Copy link
Member

Yes, that hashing of totally floating-point-unrelated things depends on rounding mode. Of course, that's the "clever trick" that allows our hashing to be fast and depend on value, but it's a weird side effect. That is odd – we should certainly always be in a standard rounding mode. I've got to try to get some sleep.

@simonbyrne
Copy link
Contributor

We've now deprecated changing the rounding mode (#27166), so this is no longer an issue.

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

4 participants