Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
ringabout authored and mildred committed Jan 11, 2021
1 parent 6892af4 commit 8aa5842
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
23 changes: 21 additions & 2 deletions lib/pure/hashes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,29 @@ else:
## Efficient hashing of integers.
hashWangYi1(uint64(ord(x)))

when defined(js):
proc asBigInt(x: float): int64 =
# result is a `BigInt` type in js, but we cheat the type system
# and say it is a `int64` type.
# TODO refactor it using bigInt once jsBigInt is ready, pending pr #1640
asm """
const buffer = new ArrayBuffer(8);
const floatBuffer = new Float64Array(buffer);
const uintBuffer = new BigUint64Array(buffer);
floatBuffer[0] = `x`;
`result` = uintBuffer[0];"""

proc hash*(x: float): Hash {.inline.} =
## Efficient hashing of floats.
var y = x + 0.0 # for denormalization
result = hash(cast[ptr Hash](addr(y))[])
let y = x + 0.0 # for denormalization
when nimvm:
# workaround a JS VM bug: bug #16547
result = hashWangYi1(cast[int64](float64(y)))
else:
when not defined(js):
result = hashWangYi1(cast[Hash](y))
else:
result = hashWangYi1(asBigInt(y))

# Forward declarations before methods that hash containers. This allows
# containers to contain other containers
Expand Down
31 changes: 30 additions & 1 deletion tests/stdlib/thashes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ discard """
targets: "c cpp js"
"""

import hashes
import std/hashes

block hashes:
block hashing:
Expand Down Expand Up @@ -75,3 +75,32 @@ block largeSize: # longer than 4 characters
doAssert hash(xx) == hash(ssl, 0, 4)
doAssert hash(xx, 0, 3) == hash(xxl, 0, 3)
doAssert hash(xx, 0, 3) == hash(ssl, 0, 3)

proc main() =
doAssert hash(0.0) == hash(0)
when sizeof(int) == 8:
block:
var s: seq[Hash]
for a in [0.0, 1.0, -1.0, 1000.0, -1000.0]:
let b = hash(a)
doAssert b notin s
s.add b
when defined(js):
doAssert hash(0.345602) == 2035867618
doAssert hash(234567.45) == -20468103
doAssert hash(-9999.283456) == -43247422
doAssert hash(84375674.0) == 707542256
else:
doAssert hash(0.345602) == 387936373221941218
doAssert hash(234567.45) == -8179139172229468551
doAssert hash(-9999.283456) == 5876943921626224834
doAssert hash(84375674.0) == 1964453089107524848
else:
doAssert hash(0.345602) != 0
doAssert hash(234567.45) != 0
doAssert hash(-9999.283456) != 0
doAssert hash(84375674.0) != 0


static: main()
main()

0 comments on commit 8aa5842

Please sign in to comment.