假设我有两个浮点数x
和y
,它们的值非常接近。
计算机上可以显示离散数量的浮点数,因此我们可以按递增顺序枚举它们:f_1, f_2, f_3, ...
。我希望在此列表中找到x
和y
的距离(即它们分别是1,2,3,......或n
个离散步骤?)
是否可以通过仅使用算术运算(+-*/
)来实现,而不是查看二进制表示?我主要对x86如何工作感兴趣。
以下近似是否正确,假设y > x
且x
和y
仅相隔几步(比如说,<100)? (可能不是......)
(y-x) / x / eps
这里eps
表示机器epsilon。 (机器epsilon是1.0和下一个最小浮点数之间的差值。)
答案 0 :(得分:3)
浮动按字典顺序排列,因此:
int steps(float a, float b){
int ai = *(int*)&a; // reinterpret as integer
int bi = *(int*)&b; // reinterpret as integer
return bi - ai;
}
steps(5.0e-1, 5.0000054e-1); // returns 9
比较浮点数时使用
答案 1 :(得分:1)
你不必直接检查二进制表示,但我认为你必须依靠它来得到一个确切的答案。
首先使用frexp()将x分成指数exp
和尾数。我相信下一个大于x的浮点数是x + eps * 2^(exp-1)
。 (“-1”是因为frexp返回的范围是[1 / 2,1}而不是[1,2]。)
如果x和y具有相同的指数,则基本完成。否则,你需要计算每个2的幂的步数,这只是1.0/eps
。换句话说,2 ^ n和2 ^(n + 1)之间的步数是1.0/eps
。
因此,对于y&gt; x,计算从x到下一个2的幂的步数;然后计算获得2小于y的最大功率所需的步数;然后计算从那里到y需要多少步骤。我认为所有这些都很容易用eps
来表达。