[英]Express highest floating point quantity that is less than 1
我正在做一些舍入计算并发生了一个问题。 对于给定的浮点类型,如何表示小于1的最大数量?
也就是说,我如何写/表示值x
,使得任何y > 0
x < 1, x + y >= 1
。
在分数中,这将是x = (q-1)/q
,其中q
是类型的精度 。 例如,如果以1/999
增量计数,则x = 998/999
。
对于给定的类型(float,double,long double),如何在代码中表示值x
?
我也想知道y
所有值是否确实存在这样的值。 也就是说,随着y's
指数变小,也许这种关系不再成立。 所以对y
一些范围限制的答案也是可以接受的。 (我希望x
的值仍然存在,关系可能无法正确表达它。)
C99定义了nextafter()
函数。 像它一样使用它
#include <math.h>
double under_one = nextafter(1, 0);
Altouht其他人是正确的,小于1
较大值是1-FLT_EPSILON
,在浮点中x < 1, x + y >= 1
对于任何y > 0
,它不能满足条件x < 1, x + y >= 1
,除非你使用向上舍入。
原因是1和之前的距离(即FLT_EPSILON
~1.2E-7)远远大于最小可表示正数FLT_MIN
,即~1.2E-38。 因此,对于(1-FLT_EPSILON)+y == (1-FLT_EPSILON) < 1
,存在一类数字(舍入到最近时为FLT_MIN ... FLT_EPSILON/2
,这是大多数系统的默认值(1-FLT_EPSILON)+y == (1-FLT_EPSILON) < 1
。
有一种方法可以获得添加到1的最低数量,从而产生大于1的最小可表达数量。这是std::numeric_limits<type>::epsilon()
。 如果您证明此数量等于您搜索的数量,那就是您想要的:
template static _Tp std :: numeric_limits <_Tp> :: epsilon()throw()[inline,static]机器epsilon:1和可表示的大于1的最小值之间的差值。
nextafter()
函数适用于@qrdl
#include <math.h>
// find next double from 1.0 working towards 0.0
double before_1 = nextafter(1.0, 0.0);
然而,要以高度便携的方式在@OP评论的编译时间值这样做:
#include <float.h>
double before_1 = 1.0 - DBL_EPSILON/FLT_RADIX;
DBL_EPSILON
是1.0和下一个更大的 double
DBL_EPSILON
之间的绝对差值。
FLT_RADIX
是浮点系统的基数(基数)。 经常2.使用像16和10这样的值。
IEEE 754浮点表示具有以下属性:对于正数而不是NaN
的数字,该顺序与作为整数查看的位模式的顺序相同。
因此,您可以将浮点数1.0的位模式重新解释为整数,递减该整数,然后再将其重新解释为浮点数,以使浮点数略低于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。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.