Skip to content

Cross v0.1.15 Breaks f32/f64 to_bits on PowerPC #313

@Alexhuszagh

Description

@Alexhuszagh

The following code worked for cross v0.1.14, so any issues were introduced with the latest release.

Targets

  • powerpc-unknown-linux-gnu
  • powerpc64-unknown-linux-gnu
  • powerpc64le-unknown-linux-gnu

Failing Code

pub fn main() {
    let f: f32 = 1e-45;
    println!("to_bits={:#b}", f.to_bits());

    let p = &f as *const f32;
    let p = p as *const i32;
    unsafe {
        println!("transmuted as integer={:#b}", *p);
    }
}

Results

to_bits=0b100
transmuted as integer=0b1

The value of f.to_bits() is 4, rather than 1, as expected, since 1e-45 is the smallest denormal 32-bit floating point number. The direct type-pun through a pointer alias gets the correct value of 1. to_bits directly calls mem::transmute, which should just pun the bytes to a new type.

Explanation

The binary representation for the IEEE-754 single-precision floating point number 1e-45 is:

0 | 00000000 | 00000000000000000000001

The first group is the sign bit, the second group is the exponent (including the hidden bit), and the third group is the significant digits (mantissa). The endianness of floats should be the same as integers on the architecture. Therefore, f.to_bits() should return 1, instead, for some unknown reason, it returns 4.

Minimal Steps to Reproduce

  1. Create a repository (cargo new --bin sample).
  2. Copy the failing code into main.rs.
  3. Run the binary on a PowerPC architecture (cross run --target powerpc-unknown-linux-gnu).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-powerpcArea: PowerPC targetsA-qemuArea: qemu runnersbug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions