我正在尝试计算在哪里是一个双精度浮点数。我需要保守的四舍五入,这意味着我需要四舍五入和四舍五入。如果舍入模式设置为 FE_UPWARDS,则代码为
double lo = -(x * -x);
double hi = x * x;
但是,这在 clang 3.4 上对我不起作用:编译器注意到“公共子表达式”并且只做一个乘法。有谁知道如何说服 clang 不要这样做,理想情况下不会损害其他优化?特别是,我想避免使用非内联函数。
我正在尝试计算在哪里是一个双精度浮点数。我需要保守的四舍五入,这意味着我需要四舍五入和四舍五入。如果舍入模式设置为 FE_UPWARDS,则代码为
double lo = -(x * -x);
double hi = x * x;
但是,这在 clang 3.4 上对我不起作用:编译器注意到“公共子表达式”并且只做一个乘法。有谁知道如何说服 clang 不要这样做,理想情况下不会损害其他优化?特别是,我想避免使用非内联函数。
我相信这可以通过将区间边界打包到 SSE 寄存器中并使用 SSE 执行所有区间操作来解决,如
http://hal.inria.fr/docs/00/28/84/56/PDF/intervals-sse2-long-paper.pdf
无论如何,这应该比我当前的代码快,并且 clang 不应该在同一指令中应用 SSE。
如果您的编译器有nextafter
,那么您可以执行以下操作,无论设置哪种舍入模式都可以:
double x2 = x*x;
double lo = nextafter(x2,-1);
double hi = nextafter(x2,x2+1);
但我不知道是否nextafter
是内联的(可能不是)。
这是一个悲伤的答案,所以我不会接受它,希望其他人有更好的解决方案:
double hi = x * x;
double lo = (2*epsilon-1)*hi;
这是安全的,因为如果我们四舍五入,