检查浮点数是不是可以无损失地转换为整数
Posted
技术标签:
【中文标题】检查浮点数是不是可以无损失地转换为整数【英文标题】:Check if a float can be converted to integer without loss检查浮点数是否可以无损失地转换为整数 【发布时间】:2018-07-08 02:08:59 【问题描述】:我想检查一个整数是否是 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);
Rust 中是否有内置选项来检查浮点数是否可以在不截断的情况下转换为整数?
行为类似于:
42.0f64.is_int() // True/ Ok()
42.23f64.is_int() // False/ Err()
换句话说,一种方法/宏/等,它允许我通过强制转换为 int 来检查我是否会丢失信息(十进制)。
我已经发现使用x.count_ones() == 1
可以有效地检查整数是否为 2 的幂。
【问题讨论】:
昨天有一篇关于它的帖子。测试x > 0
和x & (x - 1) == 0
。 ***.com/questions/48477020/…
请记住,x as u32
可能已经导致精度损失
还有:graphics.stanford.edu/%7Eseander/bithacks.html
整数可能是 2 的幂,但这并不意味着原始浮点数是。检查浮点 x
是否可以无损转换为 int n
涉及 fraction x.fract() == 0_f32
/ x == (float) n
和 spacing/overflow 的浮点:(x + 1) != x
和x < Integer.MAX_VALUE
。 (对不起javaisms)
我的问题是/是:Check if a float can be converted to integer without loss
。两种东西的力量只是我的问题动机。
【参考方案1】:
您可以使用fract 来检查是否有非零小数部分:
42.0f64.fract() == 0.0;
42.23f64.fract() != 0.0;
请注意,这仅在您已经知道该数字在范围内时才有效。如果您需要额外检查以测试浮点数是否介于 0 和 u32::MAX
之间(或介于 i32::MIN
和 i32::MAX
之间),那么您不妨进行转换并检查它是否没有丢失精度:
x == (x as u32) as f64
【讨论】:
这涵盖了分数......大于 u32::MAX 的 f64 数字呢?fract()
实际上实现为self - self.trunc()
,最好使用v.trunc() == v
代替检查。
@diginoise 你是对的,这仅适用于已知范围内的数字。
@Jmb:对,我在想分数(比如 0.3),完全不成立!
x == (x as u32) as f64
是我一直看到的这种结构。以上是关于检查浮点数是不是可以无损失地转换为整数的主要内容,如果未能解决你的问题,请参考以下文章