@@ -59,6 +59,55 @@ const mp_obj_float_t mp_const_float_pi_obj = {{&mp_type_float}, M_PI};
5959
6060#endif
6161
62+ #if MICROPY_FLOAT_HIGH_QUALITY_HASH
63+ // must return actual integer value if it fits in mp_int_t
64+ mp_int_t mp_float_hash (mp_float_t src ) {
65+ #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
66+ typedef uint64_t mp_float_uint_t ;
67+ #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
68+ typedef uint32_t mp_float_uint_t ;
69+ #endif
70+ union {
71+ mp_float_t f ;
72+ #if MP_ENDIANNESS_LITTLE
73+ struct { mp_float_uint_t frc :MP_FLOAT_FRAC_BITS , exp :MP_FLOAT_EXP_BITS , sgn :1 ; } p ;
74+ #else
75+ struct { mp_float_uint_t sgn :1 , exp :MP_FLOAT_EXP_BITS , frc :MP_FLOAT_FRAC_BITS ; } p ;
76+ #endif
77+ mp_float_uint_t i ;
78+ } u = {.f = src };
79+
80+ mp_int_t val ;
81+ const int adj_exp = (int )u .p .exp - MP_FLOAT_EXP_BIAS ;
82+ if (adj_exp < 0 ) {
83+ // value < 1; must be sure to handle 0.0 correctly (ie return 0)
84+ val = u .i ;
85+ } else {
86+ // if adj_exp is max then: u.p.frc==0 indicates inf, else NaN
87+ // else: 1 <= value
88+ mp_float_uint_t frc = u .p .frc | ((mp_float_uint_t )1 << MP_FLOAT_FRAC_BITS );
89+
90+ if (adj_exp <= MP_FLOAT_FRAC_BITS ) {
91+ // number may have a fraction; xor the integer part with the fractional part
92+ val = (frc >> (MP_FLOAT_FRAC_BITS - adj_exp ))
93+ ^ (frc & ((1 << (MP_FLOAT_FRAC_BITS - adj_exp )) - 1 ));
94+ } else if ((unsigned int )adj_exp < BITS_PER_BYTE * sizeof (mp_int_t ) - 1 ) {
95+ // the number is a (big) whole integer and will fit in val's signed-width
96+ val = (mp_int_t )frc << (adj_exp - MP_FLOAT_FRAC_BITS );
97+ } else {
98+ // integer part will overflow val's width so just use what bits we can
99+ val = frc ;
100+ }
101+ }
102+
103+ if (u .p .sgn ) {
104+ val = - val ;
105+ }
106+
107+ return val ;
108+ }
109+ #endif
110+
62111STATIC void float_print (const mp_print_t * print , mp_obj_t o_in , mp_print_kind_t kind ) {
63112 (void )kind ;
64113 mp_float_t o_val = mp_obj_float_get (o_in );
0 commit comments