diff --git a/vlib/math/bits/unsafe_bits.v b/vlib/math/bits/unsafe_bits.v index 81332db75f..764be748d1 100644 --- a/vlib/math/bits/unsafe_bits.v +++ b/vlib/math/bits/unsafe_bits.v @@ -3,13 +3,29 @@ // that can be found in the LICENSE file. module bits +union U32_F32 { + u u32 + f f32 +} + +union U64_F64 { + u u64 + f f64 +} + // f32_bits returns the IEEE 754 binary representation of f, // with the sign bit of f and the result in the same bit position. // f32_bits(f32_from_bits(x)) == x. @[inline] pub fn f32_bits(f f32) u32 { - p := *unsafe { &u32(&f) } - return p + $if tinyc { + return *unsafe { &u32(&f) } // this is faster for tcc, but causes `error: dereferencing type-punned pointer will break strict-aliasing rules` on gcc, with -cstrict + } + return unsafe { + U32_F32{ + f: f + }.u + } } // f32_from_bits returns the floating-point number corresponding @@ -18,8 +34,14 @@ pub fn f32_bits(f f32) u32 { // f32_from_bits(f32_bits(x)) == x. @[inline] pub fn f32_from_bits(b u32) f32 { - p := *unsafe { &f32(&b) } - return p + $if tinyc { + return *unsafe { &f32(&b) } + } + return unsafe { + U32_F32{ + u: b + }.f + } } // f64_bits returns the IEEE 754 binary representation of f, @@ -27,8 +49,14 @@ pub fn f32_from_bits(b u32) f32 { // and f64_bits(f64_from_bits(x)) == x. @[inline] pub fn f64_bits(f f64) u64 { - p := *unsafe { &u64(&f) } - return p + $if tinyc { + return *unsafe { &u64(&f) } + } + return unsafe { + U64_F64{ + f: f + }.u + } } // f64_from_bits returns the floating-point number corresponding @@ -37,6 +65,12 @@ pub fn f64_bits(f f64) u64 { // f64_from_bits(f64_bits(x)) == x. @[inline] pub fn f64_from_bits(b u64) f64 { - p := *unsafe { &f64(&b) } - return p + $if tinyc { + return *unsafe { &f64(&b) } + } + return unsafe { + U64_F64{ + u: b + }.f + } }