diff options
Diffstat (limited to 'erts/emulator/beam/utils.c')
-rw-r--r-- | erts/emulator/beam/utils.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index 2dd81e3ca3..aecfe04a75 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -955,12 +955,14 @@ tail_recur: UINT32_HASH_RET(external_ref_numbers(term)[0],FUNNY_NUMBER9,FUNNY_NUMBER10); case FLOAT_DEF: { - FloatDef ff; - GET_DOUBLE(term, ff); - hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]); - break; + FloatDef ff; + GET_DOUBLE(term, ff); + if (ff.fd == 0.0f) { + ff.fd = 0.0f; /* ensure pos. 0.0 */ + } + hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]); + break; } - case MAKE_HASH_CDR_PRE_OP: term = (Eterm) WSTACK_POP(stack); if (is_not_list(term)) { @@ -1474,6 +1476,9 @@ make_hash2(Eterm term) { FloatDef ff; GET_DOUBLE(term, ff); + if (ff.fd == 0.0f) { + ff.fd = 0.0f; /* ensure pos. 0.0 */ + } #if defined(WORDS_BIGENDIAN) || defined(DOUBLE_MIDDLE_ENDIAN) UINT32_HASH_2(ff.fw[0], ff.fw[1], HCONST_12); #else @@ -1893,8 +1898,8 @@ make_internal_hash(Eterm term) { FloatDef ff; GET_DOUBLE(term, ff); - if (ff.fd == 0.0) { - ff.fd = 0.0; /* ensure pos. 0.0 */ + if (ff.fd == 0.0f) { + ff.fd = 0.0f; /* ensure pos. 0.0 */ } UINT32_HASH_2(ff.fw[0], ff.fw[1], HCONST_12); goto pop_next; @@ -2079,12 +2084,14 @@ tail_recur: break; case FLOAT_DEF: { - FloatDef ff; - GET_DOUBLE(term, ff); - hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]); + FloatDef ff; + GET_DOUBLE(term, ff); + if (ff.fd == 0.0f) { + ff.fd = 0.0f; /* ensure pos. 0.0 */ + } + hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]); } break; - case MAKE_HASH_CDR_PRE_OP: term = (Eterm) WSTACK_POP(stack); if (is_not_list(term)) { @@ -2911,7 +2918,7 @@ static int cmp_atoms(Eterm a, Eterm b) */ Sint cmp(Eterm a, Eterm b) { - return erts_cmp(a, b, 0); + return erts_cmp(a, b, 0, 0); } #endif @@ -2920,9 +2927,10 @@ Sint cmp(Eterm a, Eterm b) * exact = 0 -> arith-based compare */ #if HALFWORD_HEAP -Sint erts_cmp_rel_opt(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base, int exact) +Sint erts_cmp_rel_opt(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base, + int exact, int eq_only) #else -Sint erts_cmp(Eterm a, Eterm b, int exact) +Sint erts_cmp(Eterm a, Eterm b, int exact, int eq_only) #endif { #define PSTACK_TYPE struct erts_cmp_hashmap_state @@ -3742,7 +3750,7 @@ pop_next: return 0; not_equal: - if (!PSTACK_IS_EMPTY(hmap_stack)) { + if (!PSTACK_IS_EMPTY(hmap_stack) && !eq_only) { WSTACK_ROLLBACK(stack, PSTACK_TOP(hmap_stack)->wstack_rollback); goto pop_next; } |