今天,我正在浏览一些C代码(由其他人编写),并找到了这一部分:
double someValue = ...
if (someValue < std::numeric_limits<double>::epsilon() &&
someValue > -std::numeric_limits<double>::epsilon()) {
someValue = 0.0;
}
我试图弄清楚这是否有意义。
< code>epsilon()的文档说明:
该函数返回1与大于1的最小值之间的差值,该最小值可[由双精度]表示。
这也适用于 0 吗,即 epsilon()
是大于 0 的最小值?还是有 0
到 0 epsilon
之间的数字可以用双精度
表示?
如果不是,那么比较不就等于< code>someValue == 0.0吗?
有些数字存在于0和ε之间,因为ε是1和可以在1以上表示的下一个最高数字之间的差,而不是0和可以在0以上表示的第二个最高数字的差(如果是的话,代码的作用很小):-
#include <limits>
int main ()
{
struct Doubles
{
double one;
double epsilon;
double half_epsilon;
} values;
values.one = 1.0;
values.epsilon = std::numeric_limits<double>::epsilon();
values.half_epsilon = values.epsilon / 2.0;
}
使用调试器,在main的末尾停止程序并查看结果,您将看到epsilon/2不同于epsilon、0和1。
所以这个函数取/-ε之间的值,并使它们为零。
该测试当然与someValue==0
不同。浮点数的全部思想是它们存储一个指数和一个有效数。因此,它们表示具有一定数量的二进制有效精度数字的值(在IEEE双精度的情况下为53)。可表示的值在0附近比在1附近密集得多。
要使用更熟悉的十进制系统,假设您将十进制值“存储为 4 个有效数字”并带有指数。那么下一个大于 1 的可表示值是 1.001 * 10^0,
epsilon
是 1.000 * 10^-3
。但是
1.000 * 10^
-4 也是可表示的,假设指数可以存储 -4。你可以相信我的话,IEEE双精度可以存储比epsilon
的指数少的指数。
您不能仅从这段代码中判断使用epsilon
作为绑定是否有意义,您需要查看上下文。可能epsilon
是对产生的计算中的错误的合理估计,也可能不是。
假设64位IEEE double,有一个52位尾数和11位指数。让我们把它分成几部分:
1.0000 00000000 00000000 00000000 00000000 00000000 00000000 × 2^0 = 1
大于1的最小可表示数:
1.0000 00000000 00000000 00000000 00000000 00000000 00000001 × 2^0 = 1 + 2^-52
因此:
epsilon = (1 + 2^-52) - 1 = 2^-52
0和epsilon之间有数字吗?很多…例如。最小正表示(正常)数是:
1.0000 00000000 00000000 00000000 00000000 00000000 00000000 × 2^-1022 = 2^-1022
事实上,在0和ε之间有(1022-521)×2^52=4372995238176751616
数,这是所有正可表示数的47%。。。
问题内容: 我是Java的新手,我一直在尝试实现一种用于查找三次方程式根的算法。当我计算判别式并尝试检查其相对于零的位置时,就会出现问题。 如果运行它并输入数字“ 1 -5 8 -4”,则输出如下: 我知道问题是因为双精度计算不精确。通常,判别式应为0,但最终变为0.00000000000000001236。 我的问题是,避免这种情况的最佳方法是什么?我是否应该检查数字是否介于零附近的ε之间?还是
为什么下面的返回为假?
问题内容: 有没有一种方法可以在不对位串宽度为0进行硬编码的情况下进行非零位串测试? 例如,假设我有两个表,Users和Features,每个表都带有掩码,我想对此进行测试: 匹配隐式非零结果。但是,SQL需要一个显式的布尔结果,而不是隐式的强制转换,例如: 由于多种原因,我不想在此查询中进行硬编码(或其他任何方式)。 测试或导致类型错误。奇怪的是,我可以测试,但这给出了错误的答案,因为Postg
我开发了一个程序,它创建一个书籍对象数组,并根据用户输入对它们进行排序。排序选项是author-title-pages-price,除了price排序之外,其他都可以。请帮我找出为什么我不能使用比较器对双打进行排序...我的课本课: 和排序程序:
我创建了一个,当调用变量为ISE时,它会读取相关数据的表。但是,如果我尝试将与另一个对象进行比较,无法正确读取。我想告诉脚本,如果现有CSV中的任何行与匹配,则不会将数据导出到CSV,换句话说,跳过CSV文件中的重复行。CSV可能有也可能没有多行。
我有一个jUnit测试断言两个双重对象与以下: 这很好,然后我决定将其改为使用原语double,结果发现它已被弃用,除非还提供了delta。 所以我想知道的是,在这个assertEquals中使用双对象或原语类型有什么区别?为什么使用没有增量的对象是可以的,但是使用没有增量的原语是不可取的?Java是否在后台做了一些已经考虑了默认增量值的事情? 谢谢