在我的数值模拟中,我的代码类似于以下代码段
double x;
do {
x = /* some computation */;
} while (x <= 0.0);
/* some algorithm that requires x to be (precisely) larger than 0 */
Run Code Online (Sandbox Code Playgroud)
对于某些平台上的某些编译器(例如gcc)(例如linux,x87 math),有可能x以高于双精度("具有过度精度")的方式计算.(更新:当我在这里谈到精度时,我的意思是精度/和/范围.)在这种情况下,可以想象,x <= 0即使下一次x向下舍入到双精度,它也会变为0,而compare()返回false.(和无法保证x不会在任意时间点向下舍入.)
有没有办法进行这种比较
我尝试使用(x < std::numeric_limits<double>::denorm_min())但是在使用SSE2数学时,这似乎显着减慢了循环.(我知道非正规可以减慢计算速度,但我没想到它们只是移动并比较慢.)
更新:
另一种方法是在比较之前使用volatile强制x进入内存,例如通过写入
} while (*((volatile double*)&x) <= 0.0);
Run Code Online (Sandbox Code Playgroud)
但是,根据应用程序和编译器应用的优化,此解决方案也会引入明显的开销.
更新: 任何容忍的问题是它是非常随意的,即它取决于具体的应用程序或上下文.我更愿意在没有过多精度的情况下进行比较,这样我就不必做任何额外的假设或在我的库函数的文档中引入一些任意的epsilons.
我可以期望用户空间程序中的任何"数据"指针与地址0和0xffffffff ...保持安全距离,这样我可以安全地向指针添加一个小偏移而不检查溢出吗?当p是指向常量字符缓冲区或动态分配字符串的char指针(在现代> = 32位操作系统上)时,我可以安全地假设p + n不会溢出的最大正n是多少?
为了避免混淆:我在谈论溢出检查,而不是边界检查.例如:如果你有一个带有m个字符的字符串开头的指针p,并且你想要访问正偏移量i的字符,那么你需要检查i <m或者你可以间接检查p + i < p + m.但是,在后一种情况下,您还必须确保p + i不会溢出,即您必须确保p + i> = p.
更新:好的,如果i> m,p + i无效标准C,无论p + i是否实际被解除引用或是否溢出.然而,我真正感兴趣的问题是,是否存在一个小的n,p + n 在实践中不会溢出.回答这个问题显然需要一些关于现代操作系统如何组织地址空间的知识.
Update2:听说任何一个特定的平台已经非常有趣了,即使它不具有推广性.优选地,不是一些模糊的嵌入式嵌入式.x86或基于Power的32位Win,Linux和Mac将是最有趣的.