我正在进行一些舍入计算并发生在一个问题上。对于给定的浮点类型,如何表示小于1的最大数量?
也就是说,我如何为x
编写/代表值x < 1, x + y >= 1
,y > 0
。
在分数中,这将是x = (q-1)/q
,其中q
是该类型的精度。例如,如果您以1/999
为增量计数,则x = 998/999
。
对于给定的类型(float,double,long double),如何在代码中表达值x
?
我也想知道y
的所有值是否确实存在这样的值。也就是说,当y's
指数变小时,关系可能不再成立。因此,对y
的某些范围限制的答案也是可以接受的。 (我想要的x
的值仍然存在,这种关系可能无法正确表达它。)
答案 0 :(得分:12)
C99定义nextafter()
函数。像
#include <math.h>
double under_one = nextafter(1, 0);
答案 1 :(得分:4)
Altouht其他人说得对,1
以下1-FLT_EPSILON
的值越高,浮动点就越不能满足任何x < 1, x + y >= 1
的条件 y > 0
,除非你正在使用四舍五入。
原因是1和之前的距离(FLT_EPSILON
~1.2E-7)远远大于最小可表示正数FLT_MIN
,即~1.2E-38。因此,对于FLT_MIN ... FLT_EPSILON/2
,存在一类数字((1-FLT_EPSILON)+y == (1-FLT_EPSILON) < 1
在舍入到最近时(大多数系统的默认值)。
答案 2 :(得分:2)
有一种方法可以获得添加到1的最低数量,从而产生大于1的最小可表达数量。即std::numeric_limits<type>::epsilon()
。如果您证明此数量等于您搜索的数量,那就是您想要的:
template static _Tp std :: numeric_limits&lt; _Tp&gt; :: epsilon()throw()[inline,static] 机器epsilon:1和最大值之间的差值,大于1是可表示的。
答案 3 :(得分:1)
IEEE 754浮点表示具有以下属性:对于正数且不是NaN
的数字,该顺序与作为整数查看的位模式的顺序相同。
因此,您可以将浮点数1.0的位模式重新解释为整数,递减该整数,然后再将其重新解释为浮点数,以获得略低于1的浮点数。
答案 4 :(得分:1)
根据IEEE 754标准,单精度(32位)1.0具有表示0x3F800000。我们可以用二进制写这个0 01111111(1)00000000000000000000000,这意味着:
sign = 0
biased exponent = 01111111 = 0x7F, so exponent = -23 (decimal)
mantissa = 0x800000 (the (1) in parentheses is the implied msb)
因此值为0x800000 * 2 ^ -23,即1.0。下一个最低的单精度数是
0 01111110 (1)11111111111111111111111
或0x3F7FFFFF,或0xFFFFFF * 2 ^ -24,约为0.99999994。
答案 5 :(得分:1)