你如何找到一个浮动的最接近的非同等价值? [英] How do you find a float's nearest non-equal value?

查看:120
本文介绍了你如何找到一个浮动的最接近的非同等价值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

A 浮动(又称单)值是一个4字节的值,并且应该重新present任何实际值数。的,因为它被格式化的方式,它是由关字节的有限数目,有一个最小值,它可以重新present一个最大值,并且它有一个有限precision,取决于它本身的价值。

A float (a.k.a. single) value is a 4-byte value, and supposed to represent any real-valued number. Because of the way it is formatted and the finite number of bytes it is made off, there is a minimum value and a maximum value it can represent, and it has a finite precision, depending on it's own value.

我想知道是否有一种方式来获得高于或低于一定的参考价值最接近的可能值,给出一个浮动的有限precision。用整数,这是微不足道的:一是简单地加上或减去1。但以浮动,你不能简单地增加或减少的最小浮点值,并希望它是不同的从您的原始价值。即。

I would like to know if there is a way to get the closest possible value above or below some reference value, given the finite precision of a float. With integers, this is trivial: one simply adds or subtracts 1. But with a float, you can't simply add or subtract the minimum float value and expect it to be different from your original value. I.e.

float FindNearestSmaller (const float a)
{
    return a - FLT_MIN; /* This doesn't necessarily work */
}

事实上,上述几乎不会工作。在上述情况下,回报率将普遍仍然等于 A ,因为 FLT_MIN 远远超出了precision的 A 。您可以轻松地尝试了这一点自己:它适用于例如 0.0 ,或非常小的数字顺序 FLT_MIN ,而不是0和100之间的任何东西。

In fact, the above will almost never work. In the above case, the return will generally still equal a, as the FLT_MIN is far beyond the precision of a. You can easily try this out for yourself: it works for e.g. 0.0f, or for very small numbers of order FLT_MIN, but not for anything between 0 and 100.

所以,你会怎么得到最接近但大于或小于该值 A ,由于浮点precision?

So how would you get the value that is closest but smaller or larger than a, given floating point precision?

注意:虽然我主要感兴趣的是C / C ++的答案,我认为答案是适用于大多数编程语言

Note: Though i am mainly interested in a C/C++ answer, I assume the answer will be applicable for most programming languages.

推荐答案

要找到一个浮点值的邻国的标准方法是函数函数nextafter nextafterf 浮动。第二个参数指明了方向。请记住,无穷是IEEE 754浮点法律价值,这样你就可以很好地调用函数nextafter(x,+ 1.0 / 0.0)来获得价值正上方 X ,这甚至会工作,为 DBL_MAX (而如果你写函数nextafter(X,DBL_MAX),它将返回 DBL_MAX 当应用于 X == DBL_MAX )。

The standard way to find a floating-point value's neighbors is the function nextafter for double and nextafterf for float. The second argument gives the direction. Remember that infinities are legal values in IEEE 754 floating-point, so you can very well call nextafter(x, +1.0/0.0) to get the value immediately above x, and this will work even for DBL_MAX (whereas if you wrote nextafter(x, DBL_MAX), it would return DBL_MAX when applied for x == DBL_MAX).

这是有用的,有时两个非标准方法是:

Two non-standard ways that are sometimes useful are:


  1. 访问浮动的重presentation / 双击作为的无符号整数相同的大小,以及增加或减小这个整数。浮点格式进行了精心设计,使积极的花车,分别为负花车,再presentation,看作是一个整数位,单调与重复presented浮法发展。

  1. access the representation of the float/double as an unsigned integer of the same size, and increment or decrement this integer. The floating-point format was carefully designed so that for positive floats, and respectively for negative floats, the bits of the representation, seen as an integer, evolve monotonously with the represented float.

更改舍入模式向上,并添加最小的正浮点数。最小的正浮点数也是最小的增量,可以有两个浮筒之间,所以这绝不会跳过任何浮动。最小的正浮点数为 FLT_MIN * FLT_EPSILON

change the rounding mode to upward, and add the smallest positive floating-point number. The smallest positive floating-point number is also the smallest increment that there can be between two floats, so this will never skip any float. The smallest positive floating-point number is FLT_MIN * FLT_EPSILON.

为了完整起见,我会补充说,即使没有把它的最近的默认更改舍入模式,乘以一个浮动通过(1.0F + FLT_EPSILON)产生一个数字,表示要么近邻远离零,或之后的邻居。这可能是最便宜的,如果你已经知道你要增加/减少浮动的迹象,你不介意它有时不产生近邻。功能函数nextafter nextafterf 以这样的方式指定一个的正确实施必须测试的一些特殊值和FPU状态,并因此而昂贵的它做什么。


For the sake of completeness, I will add that even without changing the rounding mode from its "to nearest" default, multiplying a float by (1.0f + FLT_EPSILON) produces a number that is either the immediate neighbor away from zero, or the neighbor after that. It is probably the cheapest if you already know the sign of the float you wish to increase/decrease and you don't mind that it sometimes does not produce the immediate neighbor. Functions nextafter and nextafterf are specified in such a way that a correct implementation on the x86 must test for a number of special values and FPU states, and is thus rather costly for what it does.

要大大有助于为零时,通过 1.0F乘 - FLT_EPSILON

To go towards zero, multiply by 1.0f - FLT_EPSILON.

这不适用于 0.0 工作,很明显,一般为较小的非规范化的数值。

This doesn't work for 0.0f, obviously, and generally for the smaller denormalized numbers.

有关其乘以 1.0F + FLT_EPSILON 提前2 ULPS只是下面的两个动力,特别是在区间[0.75 * 2 P中的值 ... 2 p )。如果你不介意做乘法和加法, X +(X *(* FLT_EPSILON 0.74))应该为所有正常工作的数字(但仍然不是零,也没有对于所有的非正规的小数字)。

The values for which multiplying by 1.0f + FLT_EPSILON advance by 2 ULPS are just below a power of two, specifically in the interval [0.75 * 2p … 2p). If you don't mind doing a multiplication and an addition, x + (x * (FLT_EPSILON * 0.74)) should work for all normal numbers (but still not for zero nor for all the small denormal numbers).

这篇关于你如何找到一个浮动的最接近的非同等价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆