我偶然发现了一些奇怪的问题:
我在acosf中得到了浮点异常(我们明确地启用了它们并使用了/ fp:strict):
我们有2个32位浮点矢量,想要计算角度。
float32 len1 = Vec_Len(vec1);
float32 len2 = Vec_Len(vec2);
float32 angle = acosf( (vec1.x * vec2.x + vec1.y * vec2.y)/(len1*len2) );
非常直接。
发生的问题是无效的Op异常。
检查计算的值显示acosf
调用中的表达式求值为double
(记住:在C浮点表达式中总是提升为double),值略大于1.0
(欢迎来到浮点数学世界)。
到目前为止一切顺利 - BUT 四舍五入到float32精度的表达式正是1.0f
(我还检查了二进制表示)。
那么为什么地狱会触发acosf
这个例外?在参数传递时,表达式是否应该被截断/舍入/浮动?
经过简短的思考:我在“Microsoft Visual Studio 10.0 \ VC \ include \ math.h”中找到了这个:
#define acosf(x) ((float)acos((double)(x)))
这是文件中的一个定义,但它似乎是活动的,因为我可以在预处理文件中看到它。
这是'合法'吗? 在我看来,这违反了“假设”规则。
这个定义(也在文件中)似乎对我来说更合适
inline float acosf(_In_ float _X)
{return ((float)acos((double)_X)); }