【发布时间】:2019-02-20 09:02:10
【问题描述】:
我想知道值 1/256、2/256、3/256、... 254/256 和 255/256 是否可以精确地表示为 f32。现在,聪明的人会思考浮点数是如何工作的并找出答案。但我想在程序中检查一下。我要检查的所有数字都是分数,我控制值(即没有用户输入)。
我是从这个开始的:
for n in 1u8..=255 {
let f = (n as f32) / 256.0;
println!("{}", f);
}
但是现在呢?我尝试打印该数字以查看是否有大量重复数字,但这并不总是有效。例如,0.4 不能完全表示:
println!("{}", 0.4); // prints "0.4"
println!("{:.20}", 0.4); // prints "0.40000000000000002220"
在这里,我们必须手动提高精度才能看到问题。无论如何,查看字符串输出似乎是一个次优的解决方案。
首先我认为f32 上可能有一个方法,但这没有多大意义,不是吗?因为当 f32 已经存在时,没有办法知道它的值是否是预期的。所以我们必须以某种方式找出何时创建浮点值并与“理想化”值进行比较?
有什么方法可以检查一个值是否可以精确地表示为f32?
【问题讨论】:
-
这是一个“几乎总是”有效的测试,尽管它需要改进:你从两个表示不可约分数
a/b的任意大整数开始。如果b不是 2 的精确幂(即b不是 1,2,4,8,...),那么您的数字将无法准确表示。如果a大于大约 2^23,那么它将无法精确表示。否则(即如果a<2^23和b是 2 的精确幂),它很可能是可表示的。但是,我跳过了很多怪癖,将所有内容都考虑在内绝非易事。 -
@Jojonete 这很少值。也许 f32 不是在这种情况下使用的编码。
-
@Darth:为什么值很少?你有一个分子和一个分母。只有分母必须是 2 的幂,而不是分子,然后你才有可能使用指数,所以你几乎有 2^32 个可能的值。
-
@Jojonete 评论的一些额外信息:(1)使用最大公约数(
A/B =a/b与a=A/gcd(A,B)和b=B/gcd(A,B))将A/B减少为不可约分数。 (2)check ifbis a power of two。 (3)你必须摆弄一下指数才能找出b的范围
标签: rust floating-point ieee-754