EDIT
已解决
解决方案是使用long double
和sin
的{{1}}版本:cos
和sinl
。
这是我在这里的第一篇文章,所以请忍受:)。
我今天来到这里,是您对我在使用C应用程序时遇到的一个小问题的意见。基本上,我正在计算扩展卡尔曼滤波器,并且我的一个公式(存储在变量中)具有多次sin和cos计算,同一行中总共至少有16次计算。我想减少完成计算所需的时间,因此我们的想法是分别计算每个cos和sin,将它们存储在变量中,然后将变量替换回公式中。 所以我这样做了:
cosl
ComputationType 是 Double 类型的宏定义(重命名)。我知道它看起来很丑陋,可能有很多不必要的强制转换,但是此代码是在Python中生成的,并且经过专门设计。...
此外, compute_cos 和 compute_sin 的定义如下:
const ComputationType sin_Roll = compute_sin((ComputationType)(Roll));
const ComputationType sin_Pitch = compute_sin((ComputationType)(Pitch));
const ComputationType cos_Pitch = compute_cos((ComputationType)(Pitch));
const ComputationType cos_Roll = compute_cos((ComputationType)(Roll));
我的问题是我从“优化”公式中获得的价值与原始价值不同。
我将同时发布两者的代码,并提前致歉,因为它非常丑陋且难以遵循,但可以看到替换了cos和sin的要点。这是我的任务,需要清理和优化它,但是我正在逐步进行以确保不引入错误。
因此,新值是:
#define compute_sin(a) sinf(a)
#define compute_cos(a) cosf(a)
原来是:
ComputationType newValue = (ComputationType)(((((((ComputationType)-1.0))*(sin_Pitch))+((DT)*((((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(cos_Pitch)*(cos_Roll))+(((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(cos_Pitch)*(sin_Roll)))))*(cos_Pitch)*(cos_Roll))+((((DT)*((((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(cos_Roll)*(sin_Pitch))+(((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(sin_Pitch)*(sin_Roll))))+(cos_Pitch))*(cos_Roll)*(sin_Pitch))+((((ComputationType)-1.0))*(DT)*((((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(cos_Roll))+((((ComputationType)-1.0))*((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(sin_Roll)))*(sin_Roll)));
我想要的是获得与原始公式相同的值。为了比较它们,我使用了 memcmp 。
欢迎任何帮助。谢谢。:p。
EDIT
我还将发布获得的值。
新值:-1.2214615708217025e-005
原始值:-1.2214615708215651e-005
在某种程度上它们是相似的,但是应用程序对安全性至关重要,因此有必要验证结果。
答案 0 :(得分:0)
有两个原因使您无法达到期望。 通过更改代码,可以以微妙的方式调整所使用的机器指令,这将影响最终值。 例如,如果最初使用融合的乘法和加法,并且不再发生这种情况,它将改变结果。 您没有提到目标体系结构。一些架构在浮点流水线中保留超过64位。这些额外的位在被强制放入64位内存时会四舍五入。再次更改其工作方式将对最终输出产生较小的影响。