【问题标题】:Why is printf showing -1.#IND for FPTAN results?为什么 printf 显示 FPTAN 结果的 -1.#IND?
【发布时间】:2009-04-13 12:19:11
【问题描述】:

我正在开发一个从表达式生成汇编代码的程序。所需的函数之一是 tan(x),它目前使用以下代码序列工作(地址在运行时填写):

fld [0x00C01288];
fld st(0);
fsin;
fld st(1);
fcos;
fdivp;
fst [0x0030FA8C];

但是,我想改用FPTAN 操作码,所以我尝试使用以下代码:

fld [0x00C01288];
fptan;
fincstp;
fst [0x0030FA8C];

测试程序使用 printf 显示存储在 0x30FA8C 的结果,但对于第二个序列,结果显示为 -1.#IND(第一个使用 cos 和 sin 工作正常)。如果我尝试在调试器中检查内存地址或浮点堆栈顶部的值,它会显示为正确的数字。

所以,我的问题是:为什么 printf 显示 -1.#IND,我该如何解决?

0x00C01288 处的值是双精度 0.5 两种情况下的结果都是 ~0.5463024898

我的第一个想法是存储的值是同一数字的不同表示,但检查存储在 0x0030FA8C 的值显示在这两种情况下它都是 0x3FE17B4F5BF3474A。

我不明白为什么 printf 函数的相同输入会产生不同的输出...

任何帮助或建议将不胜感激。

编辑:调用 printf 的来源:

#include "FridgeScript.h"
#include <stdio.h>
#include <math.h>

char test[] = "a=tan(0.5);";

int main(int c, char** s)
{
    unsigned int SC = FSCreateContext();

    double a = 0.0;
    FSRegisterVariable(SC, "a", &a);

    unsigned int CH = FSCompile(SC, test);
    if(CH) FSExecute(SC, CH);

    printf("a: %.10g\r\n", a);
    printf("hex a: %I64X", a);

    FSDestroyContext(SC);
    return 0;
}

【问题讨论】:

  • 你能否展示一下使用 printf 函数的源代码?
  • 还有很多其他的东西……但我还是会添加它。
  • "-1.#IND" 是 printf 表示 NaN 的方式。我没有其他帮助可以添加,但这可能是一些有用的琐事......

标签: c++ assembly floating-point x86


【解决方案1】:

让我把一些东西扔在那里:使用怎么样

fstp st(0);

而不是

fincstp;

fincstp 上的文档说它不等同于从堆栈中弹出项目,因为它会将该位置标记为已填充 - 也许这会弄乱 printf 内部的浮点处理?

(你可能猜到我不知道我在说什么。但也许这会给你一个想法?)

【讨论】:

  • 这完美地解决了它。谢谢。我想 va_args 依赖于带有 printf 调用约定或其他东西的浮点堆栈......
  • 通常 printf() 使用堆栈作为参数,并且可能在 x86-64 上使用一些寄存器。它通过解析格式字符串知道要寻找多少个参数。当 printf() 尝试使用 FPU 时,IMO 出现了问题。
  • 对于那些不知道自己在说什么的人来说,这是一个非常好的猜测:-) +1 是一个很好的猜测。
  • 巴斯蒂安 - 同意。也许有一个浮动堆栈溢出?据我所知,当您将堆栈条目标记为已使用时会发生这种情况。
【解决方案2】:
fld [0x00C01288];
fptan;
fincstp;
fst [0x0030FA8C];

在我看来,这段代码执行后,切线仍然在st0。你不应该使用fstp 而不是fst吗?

【讨论】:

  • 这听起来也与我的回答有关。 fp 堆栈中仍然有东西。
  • fst 应该存储在 0x0030FA8C,调试器显示确实写在那里。由于 st(0) 用于返回值,因此它也必须留在那里,以便表达式可以像,例如"a = b = tan(0.5);"
【解决方案3】:

也许您的 FST 指令只存储浮点结果,而第二个 dword 仍未初始化?

我在汇编代码中没有看到任何大小前缀。通常你会看到类似的东西:

  FST [dword ptr some_address]

  or 

  FS [qword ptr some_address]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-11
    • 2010-09-25
    • 2018-04-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多