- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在某些情况下,您知道某个浮点表达式始终为非负数。例如,在计算 vector 的长度时,会出现 sqrt(a[0]*a[0] + ... + a[N-1]*a[N-1])
(注意:我知道 std::hypot
,这与问题无关),并且平方根下的表达式显然是非负的。然而,海湾合作委员会outputs以下组件适用于 sqrt(x*x)
:
mulss xmm0, xmm0
pxor xmm1, xmm1
ucomiss xmm1, xmm0
ja .L10
sqrtss xmm0, xmm0
ret
.L10:
jmp sqrtf
x*x
的结果为零,如果结果为非负,则执行
sqrtss
指令,否则调用
sqrtf
.
x*x
总是非负的,所以它跳过比较和 sqrtf
调用,而不编写内联汇编?
-ffast-math
的事情。 ,
-fno-math-errno
, 或
-ffinite-math-only
(尽管这些确实解决了问题,感谢 ks1322、harold 和 Eric Postpischil 在评论中)。
x*x
为非负”应解释为
assert(x*x >= 0.f)
,所以这也排除了
x*x
的情况是 NaN。
最佳答案
你可以写assert(x*x >= 0.f)
作为编译时 promise 而不是运行时检查,在 GNU C 中如下所示:
#include <cmath>
float test1 (float x)
{
float tmp = x*x;
if (!(tmp >= 0.0f))
__builtin_unreachable();
return std::sqrt(tmp);
}
if(!x)__builtin_unreachable()
包裹在一个宏中,并称它为
promise()
或其他。)
tmp
的 promise 。是非 NaN 和非负数。我们仍然得到 (
Godbolt ) 相同的封装 asm 序列,用于检查
x>=0
否则调用
sqrtf
设置
errno
.
据推测,在其他优化通过之后,扩展为比较和分支,所以编译器了解更多信息无济于事。
sqrt
的逻辑中的遗漏优化当
-fmath-errno
已启用(不幸的是默认情况下启用)。
-fno-math-errno
,这是全局安全的
errno
,这是 100% 安全的。 .没有人想要那样,这就是 NaN 传播和/或记录屏蔽 FP 异常的粘性标志的用途。例如C99/C++11
fenv
通过
#pragma STDC FENV_ACCESS ON
访问然后函数像
fetestexcept()
.请参阅
feclearexcept
中的示例这表明使用它来检测除以零。
errno
是全局性的。
fenv
.理想支持
-fmath-errno
会尽可能便宜,但很少有人真正使用
__builtin_unreachable()
或其他排除 NaN 输入的事情可能使开发人员不值得花时间实现优化。不过,如果您愿意,您可以报告遗漏优化错误。
mxcsr
SSE/AVX 数学或其他 ISA 中的硬件 FPU 的状态/控制寄存器。在 FPU 可以检测异常的硬件上,高质量的 C++ 实现将支持诸如
fetestexcept()
之类的东西。 .如果不是,那么数学-
errno
可能也不起作用。
errno
因为数学是一个陈旧的过时设计,默认情况下 C/C++ 仍然坚持使用,现在被广泛认为是一个坏主意。它使编译器更难有效地内联数学函数。或者也许我们并不像我想的那样坚持下去:
Why errno is not set to EDOM even sqrt takes out of domain arguement?解释了在数学函数中设置 errno 在 ISO C11 中是可选的,并且实现可以指示它们是否这样做。大概也在 C++ 中。
-fno-math-errno
与值(value)改变优化类似 -ffast-math
或 -ffinite-math-only
. 您应该强烈考虑全局启用它,或者至少为包含此功能的整个文件启用它。
float test2 (float x)
{
return std::sqrt(x*x);
}
# g++ -fno-math-errno -std=gnu++17 -O3
test2(float): # and test1 is the same
mulss xmm0, xmm0
sqrtss xmm0, xmm0
ret
-fno-trapping-math
同样,如果您不打算使用
feenableexcept()
来揭开任何 FP 异常的掩码. (尽管此优化不需要该选项,但只有
errno
设置废话是这里的问题。)。
-fno-trapping-math
不假设没有 NaN 或任何东西,它只假设像 Invalid 或 Inexact 这样的 FP 异常不会实际调用信号处理程序,而不是产生 NaN 或舍入结果。
-ftrapping-math
是默认值,但
it's broken and "never worked" according to GCC dev Marc Glisse . (即使启用它,GCC 也会进行一些优化,这些优化可以将异常数量从零变为非零,反之亦然。并且它会阻止一些安全优化)。但不幸的是,
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54192 (默认关闭)仍然打开。
-ftrapping-math
,但同样非常罕见的是,您想要它而不是在一些数学运算之后检查标志,或检查 NaN。无论如何,它实际上并没有保留确切的异常语义。
-fno-trapping-math
的情况错误地阻止了安全优化。 (即使在提升了一个潜在的陷阱操作以便 C 无条件地执行它之后,gcc 也会使非向量化的 asm 有条件地执行它!因此它不仅阻止向量化,而且与 C 抽象机相比,它改变了异常语义。)
关于c++ - 如何强制 GCC 假定浮点表达式为非负数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57673825/
这个问题已经有答案了: Invalid types 'double [100][double]' for array subscript (3 个回答) 已关闭 6 年前。 我已复制下面的整个代码并在
您有 2 个功能; f(x)= x(((x+1)^(1/2))-(x^(1/2))) g(x)= x/(((x+1)^(1/2))+(x^(1/2))) 哪个更准确? 旁注:如果你能解释为什么,
我正在从事一个关于java的研究项目,其中必须完成一些艰难的计算。然而,我已经完成了大部分工作,但停留在某个点上。我必须计算以下内容: (2.1-2.3) raised to power 0.3. 但
int main() { float x = 50; float y = 1/x; float result = y * x; float test = 41;
有没有安全的方法来可靠地确定整数类型 T可以存储浮点整数值 f (所以 f == floor(f) )没有任何溢出? 请记住,不能保证浮点类型 F与 IEC 559 (IEEE 754) 兼容,并且有
// value will always be in the range of [0.0 - maximum] float obtainRatio(float value, float maximum
就在今天,我遇到了我们正在使用的第三方软件,在他们的示例代码中,有以下内容: // Defined in somewhere.h static const double BAR = 3.14; //
是否有推荐的方法来清除 jQuery Flot 图表?我在 API 引用中找不到任何内容。 最佳答案 “清除”是指“破坏整个图表”还是只是清除数据? 要核对整个图表:$('#canvas_id').e
我正在学习单精度并想了解错误传播。根据this nice website ,加法是一个危险的操作。 所以我编写了一个小的 C 程序来测试错误累积的速度。我不完全确定这是否是一种有效的测试方法。如果是,
我正在尝试查询数据库,我需要获取权重等于 60.5 的客户列表。问题是 60.5 是一个实数,我以前从未在 where 子句中使用实数查询过数据库。 我已经尝试过这个: SELECT Name FRO
这是我的“ProjectEntity”类中的代码部分(我在其中使用 hibernate 进行 SQL 调用) @Column(name = "BUDGET") private float budget
我用 Haskell 编写了一个应用程序,它调用 Z3 求解器来解决一些复杂公式的约束。感谢 Haskell,我可以快速切换正在使用的数据类型。 当使用 SBV 的 AlgReal 类型进行计算时,我
在 C 中 double/float 有一个集合类型说明符:%f %F %g %G %e %E .有什么区别吗 %f和 %F , %g和 %G , %e和 %E ? 根据 printf和 scanf输
我正在开发一个适用于 Android 的可视化应用程序(包括运行 Android 2.2 的旧设备)。 我的应用程序的输入模型包含一个区域,该区域通常由数万个顶点组成。典型模型有 50000-1000
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 6 年前。 Improve this ques
我被要求编写一个程序来查找我大学中两个输入的总和,因此我应该首先检查输入是否有效。 例如,如果我输入 2534.11s35,程序应该检测到它不是该程序的有效输入,因为输入中存在 s。 最佳答案 to
我正在尝试降低 FPGA 的逻辑利用率,但在网上找不到任何好的 float fastpow。我所说的“好”是指充分减少所使用的逻辑。如果我使用双版本我几乎没有什么改进。如果我使用其他依赖日志的 flo
我有一个 128 字节的内存位置。我尝试用从 1...127 开始的数据填充内存。 我需要编写一个代码来获取两个参数,如偏移量、数据类型。根据参数,我需要将内存中的数据转换为提到的特定数据类型。 举个
我希望能够做到以下几点: float func() { if( error ) return InvalidFloatingPointValue; else return 0.0f;
假设我有两个 float ,我想比较它们。如果一个大于另一个,程序应该采用一个 fork。如果情况正好相反,它应该走另一条路。并且它应该做同样的事情,如果被比较的值在一个仍然应该使它比较真实的方向上被
我是一名优秀的程序员,十分优秀!