Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_types_fd_cast_h 2 : #define HEADER_fd_src_flamenco_types_fd_cast_h 3 : 4 : #include "../../util/bits/fd_float.h" 5 : 6 : /* From https://doc.rust-lang.org/rust-by-example/types/cast.html 7 : 8 : Since Rust 1.45, the `as` keyword performs a *saturating cast* 9 : when casting from float to int. If the floating point value exceeds 10 : the upper bound or is less than the lower bound, the returned value 11 : will be equal to the bound crossed. */ 12 : 13 : FD_PROTOTYPES_BEGIN 14 : 15 : #if FD_HAS_DOUBLE 16 : 17 : /* Cast a double to unsigned long the same way as rust by suturating. 18 : Saturate to 0 if the value is negative or NaN. 19 : Saturate to ULONG_MAX if the value is greater than ULONG_MAX. */ 20 : FD_FN_CONST static inline ulong 21 936186 : fd_rust_cast_double_to_ulong( double f ) { 22 936186 : ulong u = fd_dblbits( f ); 23 : /* Check if the exponent is all 1s (infinity or NaN )*/ 24 936186 : if( fd_dblbits_bexp( u )==0x7FFUL ) { 25 : /* Check if the mantissa is 0 (infinity) */ 26 9 : if( fd_dblbits_mant( u )==0 ) { 27 6 : return ULONG_MAX; 28 6 : } else { 29 : /* NaN case */ 30 3 : return 0; 31 3 : } 32 9 : } 33 : 34 : /* If the value is negative saturate to 0 */ 35 936177 : if( fd_dblbits_sign( u )==1 ) { 36 3 : return 0; 37 3 : } 38 : 39 : /* Saturate to max unsigned long value */ 40 936174 : if( f>=(double)ULONG_MAX ) { 41 12 : return ULONG_MAX; 42 12 : } 43 : 44 : /* Normal value, cast to unsigned long */ 45 936162 : return (ulong)f; 46 936174 : } 47 : 48 : #endif /* FD_HAS_DOUBLE */ 49 : 50 : FD_PROTOTYPES_END 51 : 52 : #endif /* HEADER_fd_src_flamenco_types_fd_cast_h */