gpt4 book ai didi

c - 简单浮点运算的奇怪结果 - FPU 内部状态错误?

转载 作者:太空狗 更新时间:2023-10-29 15:34:13 26 4
gpt4 key购买 nike

我有一个软件项目,在这个项目中,我有时会从小型、简单的浮点运算中得到奇怪的结果。我假设我遗漏了一些东西,并且想要一些关于如何调试以下问题的提示:

(使用的编译器是MS VC 6.0,也就是Microsoft C编译器的12版)

第一个异常:

extern double Time, TimeStamp, TimeStep;  // History terms, updated elsewhere
void timer_evaluation_function( ) {
if ( ( Time - TimeStamp ) >= TimeStep ) {
TimeStamp += TimeStep;
timer_controlled_code( );
}
{....}

由于某种原因,计时器评估失败,计时代码从未执行。在调试器中,没有问题可以看到触发条件实际上为真,但 FPU 拒绝找到肯定的结果。以下代码段虽然执行了相同的操作,但没有出现问题。通过插入一个可能允许失败的虚假评估来回避这个问题。

我猜测 FPU 状态在某种程度上被之前执行的操作所污染,并且有一些编译器标志可以提供帮助?

第二个异常:

double K, Kp = 1.0, Ti = 0.02;
void timed_code( ){
K = ( Kp * ( float ) 2000 ) / ( ( float ) 2000 - 2.0F * Ti * 1e6 )
{....}

结果是#IND,即使调试器将方程计算为大约 0.05。当使用 fld 指令将 2.0F 值加载到 FPU 中时,#IND 值出现在 FPU 堆栈中。前面的指令使用 fild 指令将整数值 2000 作为双 float 加载。一旦 FPU 堆栈包含 #IND 值,所有内容都将丢失,但调试器在计算公式时再次没有问题。稍后,这些操作会返回预期的结果。

此外,FPU 问题再次直接发生在函数调用之后。我是否应该在每个新函数之后插入清除 FPU 状态的浮点运算?是否有可能以某种方式影响 FPU 的编译器标志?

在这一点上,我很感激所有提示和技巧。

编辑:我设法通过在顶级函数中首先调用汇编函数 EMMS 来避免这个问题。这样,FPU 就清除了任何与 MMX 相关的垃圾,这些垃圾可能是在调用我的代码的环境中创建的,也可能不是。看来FPU的状态并不是想当然的。

//弗兰克

最佳答案

不知道可能是什么问题,但在 x86 上,FINIT 指令会清除 FPU。为了检验您的理论,您可以将其插入代码中的某处:

__asm {
finit
}

关于c - 简单浮点运算的奇怪结果 - FPU 内部状态错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/480562/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com