C-双重类型变量:相同的公式,不同的值

时间:2018-11-30 07:36:19

标签: c

EDIT

已解决

解决方案是使用long doublesin的{​​{1}}版本:cossinl


这是我在这里的第一篇文章,所以请忍受:)。

我今天来到这里,是您对我在使用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

在某种程度上它们是相似的,但是应用程序对安全性至关重要,因此有必要验证结果。

1 个答案:

答案 0 :(得分:0)

有两个原因使您无法达到期望。 通过更改代码,可以以微妙的方式调整所使用的机器指令,这将影响最终值。 例如,如果最初使用融合的乘法和加法,并且不再发生这种情况,它将改变结果。 您没有提到目标体系结构。一些架构在浮点流水线中保留超过64位。这些额外的位在被强制放入64位内存时会四舍五入。再次更改其工作方式将对最终输出产生较小的影响。