检查浮点数是否可以转换为整数而不会丢失

m00*_*0am 4 idiomatic rust

我想检查一个整数是否是2的幂.我的标准方法是看是否log?(x)是一个整数值,但我发现没有优雅的方法来做到这一点.我的方法如下:

let x = 65;

let y = (x as f64).log(2.0);

// Compute the difference between y and the result of
// of truncating y by casting to int and back
let difference = y - (y as i64 as f64);

// This looks nice but matches on float values will be phased out
match difference {
    0.0 => println!("{} is a power of 2", x),
    _ => println!("{} is NO power of 2", x),
}

// This seems kind of clunky
if difference == 0.0 {
    println!("{} is a power of 2", x);
} else {
    println!("{} is NO power of 2", x);
}
Run Code Online (Sandbox Code Playgroud)

Rust中是否有内置选项来检查浮点数是否可以转换为整数而不截断?

表现得像的东西:

42.0f64.is_int() // True/ Ok()
42.23f64.is_int() // False/ Err()
Run Code Online (Sandbox Code Playgroud)

换句话说,一个方法/宏/等允许我通过转换为int来检查我是否会丢失信息(小数).


我已经发现检查整数是否为2的幂可以有效地完成x.count_ones() == 1.

Jmb*_*Jmb 7

您可以使用fract来检查是否存在非零小数部分:

42.0f64.fract() == 0.0;
42.23f64.fract() != 0.0;
Run Code Online (Sandbox Code Playgroud)

请注意,这仅在您已知道该数字在范围内时才有效.如果你需要一个额外的检查来测试浮点数在0和u32::MAX(或之间i32::MINi32::MAX)之间,那么你也可以进行转换并检查它是否没有丢失精度:

x == (x as u32) as f64
Run Code Online (Sandbox Code Playgroud)

  • `fract()` 实际上是作为 `self - self.trunc()` 实现的,最好使用 `v.trunc() == v` 进行检查。 (4认同)
  • `x == (x as u32) as f64` 是我一直以来看到的这种结构。 (2认同)