我感兴趣的是为数据类型为double(8字节,64位)获得容差范围+ - e-8。
例如: 0.123456782456789
我想获得这个小于8位小数的正/负容差范围。
他们将是:
低范围= 0.123456781456789
高范围= 0.123456783456789
注意小数点后第9位的区别。
如果输入是以十六进制给出的double。我需要在十六进制中添加或减去什么?由于这是一个双精度型,它将包含4个数据字。我需要在第3个数据字中添加/减去256(十进制)吗?
例如:
3FBF 9ADD 1B1F 0D35是0.123456782456789的十六进制
所以...低和高范围是:
3FBF 9ADD 1 * A * 1F 0D35
3FBF 9ADD 1 * C * 1F 0D35
答案 0 :(得分:1)
要计算包含x的x |•10 -8 范围内的点的区间[a,b],设置a和b:
double t = fabs(x) * 1e-8;
double a = x-t;
double b = x+t;
这是近似值,因为舍入误差可能会使a或b略微不准确。如果您希望间隔绝对包含所有点,则可以使用略高于1e-8
的值,或者您可以使用更高级的技术。
一些警告:
如果您使用间隔作为测试的一部分来确定某个计算值是否“几乎等于”另一个值,那么确定必须的间隔有多大需要分析浮动 - 使用的点操作和涉及的值。根据情况,浮点值可能产生从零到无穷大的误差。在任何情况下,甚至在“典型”情况下,都不可能说明任何单一数量的容差。
确定区间可能的大小需要确定应用程序可接受的错误。接受不等的值等于允许计算错误意味着您的程序有时会接受真正不相等的相等值(如果精确计算,没有错误)。因此,您需要确定在程序产生不可接受的结果之前,间隔的大小。
显然,如果间隔必须大于可能,那么您的程序就会被破坏;这种使用间隔不起作用。在这种情况下,您必须重新设计浮点运算以减少错误或重新设计程序,否则将避免这种情况。
使用浮点数的表示来读取或更改其值通常是个坏主意。这样做需要特别注意编译器或平台规范的细节。 (特别是,似乎在测试中起作用的代码实际上可能会破坏,因为它不受编译器的支持,并且如果使用不同版本的编译器或编译开关会断开,例如用于调试的开关和优化,改变。)另外,访问浮点数表示的代码通常是不可移植的。 (最值得注意的是,一些平台以“小端”顺序存储双字节的字节,有些平台以“大端”顺序存储字节。还有其他可移植性问题。)即使代码被正确编写以访问表示一个浮点数,它可能比其他方法慢。
对于大于10 -8 的容差,使用1e-8
计算间隔可能就足够了。也就是说,您可以使用普通的浮点运算,并且不必计算浮点数的ULP或访问其表示。但是,如果您确实想要计算IEEE-754浮点数的ULP,则可以使用this answer中的代码访问其表示形式。该代码是为float
而不是double
编写的,但您可以将FLT
更改为DBL
以更改其使用的常量。当然,也要将float
更改为double
。