为什么 float 会变成 NaN

why float become NaN

提问人:Rudra Kachhia 提问时间:10/1/2023 更新时间:10/1/2023 访问量:89

问:

#include <stdio.h>

int main()
{
    int i = 2, j = 4;
    float b;
    
    b = j / i * i;
    
    printf("%f\n", j / i * i);
    printf("%f\n", b);
    return 0;
}

输出为

-1.#QNAN0
4.000000

虽然这段代码

#include <stdio.h>

int main()
{
    int i = 2, j = 4;
    float b;
    
    b = j / i * i;
    
    printf("%f\n", b);
    printf("%f\n", j / i * i);
    return 0;
}

给出输出

4.000000
4.000000

为什么会这样

我尝试在vs代码中运行它,但结果与预期不符。

c 浮点 类型转换

评论

0赞 Cem Polat 10/1/2023
您需要将 j/i*i 结果转换为浮点数。
4赞 Weather Vane 10/1/2023
j / i * i是一个值,但期望 或 。int%ffloatdouble
1赞 dimich 10/1/2023
可能在您的情况下,浮点参数是在 FPU 寄存器中传递的。因此,在第二个示例中,UB 打印了上一个函数调用中使用的 FPU 寄存器的“正确”(无)内容。
1赞 Weather Vane 10/1/2023
@MichaelM。因为为格式说明符传递错误的类型是未定义的行为,所以你得到的就是你得到的,而不是别人得到的。
1赞 n. m. could be an AI 10/1/2023
请参阅 stackoverflow.com/questions/57842756/...

答:

3赞 chux - Reinstate Monica 10/1/2023 #1

为什么 float 会变成 NaN

打印的输出并不指示浮点数变为 NaN,因为浮点数不正确并调用了未定义的行为 (UB)。printf()

  • 节省时间。启用所有编译器警告。启用良好的编译会抱怨不匹配。

  • 将打印说明符与参数类型匹配。 期望 或 调用 。如 ,也是一个 .
    使用不匹配的集合会导致未定义的行为 (UB)。任何事情都可能发生。当 FP 和整数参数以不同的方式传递(在发出的代码中)时,一种常见的 UB 表现形式,函数最终会从错误的位置(之前遗留的)或未初始化的 () 值获取数据。
    "%f"floatdoubleprintf()i, jintj / i * iintprintf()-1.#QNAN0

  • “但结果不如预期” --> 当UB发生时,不要期望好的结果。

#include <stdio.h>

int main() {
    int i = 2, j = 4;
    double b;
    
    b = j / i * i;
    
    // printf("%f\n", j / i * i);
    printf("%d\n", j / i * i);
    // or 
    printf("%f\n", (double) j / i * i);

    printf("%f\n", b);
    return 0;
}

提示:通常是 C 语言中浮点类型的最佳选择。只有在您有令人信服的理由时才使用。@Tom Karzesdoublefloat