浮动到双重误解???G++

float to double misinterpretation??? g++

本文关键字:误解 G++      更新时间:2023-10-16

由于某种原因,我收到以下警告

filename.cpp:99:53: warning: narrowing conversion of ‘sin(((double)theta))’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]
filename.cpp:99:66: warning: narrowing conversion of ‘cos(((double)theta))’ from ‘double’ to ‘float’ inside { } [-Wnarrowing]

这听起来像是试图使用"双cos(double("等而不是"float cos(float("等。我一直在尝试想更多方法向编译器建议这一点,但一无所获。我该怎么做才能解决这个问题?

void foo(float theta)
{
    theta = (float)M_PI*theta/180.0f;
    MyClass variable = { 1.0f,    0.0f,         0.0f,   0.0f,
                         0.0f, cos(theta), -sin(theta), 0.0f,
                         0.0f, sin(theta),  cos(theta), 0.0f,
                         0.0f,     0.0f,        0.0f,   1.0f };
    bob = variable;
}

谢谢


编辑:将其更改为此会使警告消失,但我仍然宁愿知道问题是什么

float C = cos(theta), S = sin(theta);
MyClass variable = { 1.0f,    0.0f,         0.0f,   0.0f,
                 0.0f, C, -S, 0.0f,
                 0.0f, S,  C, 0.0f,
                 0.0f,     0.0f,        0.0f,   1.0f };
您需要使用 std::

sin 和 std::cos 代替 sincos,以便获得正确的重载版本。您可以实时看到差异:

MyClass variable = { 1.0f,    0.0f,         0.0f,   0.0f,
                     0.0f, std::cos(theta), -std::sin(theta), 0.0f,
                     0.0f, std::sin(theta),  std::cos(theta), 0.0f,
                     0.0f,     0.0f,        0.0f,   1.0f };

C 库中的函数是否首先在全局命名空间中声明是未指定的行为 C++草案标准部分 17.6.1.2 标题4 段说(强调我的(:

除第 18 至 30 条和附录 D 中另有说明外,每个标头 cname 的内容应与相应的标头名称.h 的内容相同,如 C 标准库 (1.2( 或 C Unicode TR 中指定的那样,视情况而定,就像包含一样。但是,在C++标准库中,声明(在 C 中定义为宏的名称除外(位于命名空间 std 的命名空间范围 (3.3.6( 内。 未指定这些名称是否首先在全局命名空间范围内声明,然后通过显式 using-声明 (7.3.3( 注入命名空间 std。

因此,在 C 库函数位于全局命名空间中的情况下,您将获得只需要双倍的 cos 和 sin 版本,这与我们看到的行为一致。

看起来你正在使用 sin/cos 的 C 版本。如果没有其他信息,很难说为什么,但解决方法可能是使用 C 函数 sinf/cosf 或确保 std::sin(( 使用C++函数。

编译器抱怨您正在使用一个浮点数,而它需要一个双精度值。可以显式强制转换每个使用,也可以只创建本地双精度。

我会重写您的示例,如下所示:

void foo(float theta)
{
    double rad = (double)M_PI*theta/180.0f;
    MyClass variable = { 1.0f,    0.0f,     0.0f,   0.0f,
                         0.0f, cos(rad), -sin(rad), 0.0f,
                         0.0f, sin(rad),  cos(rad), 0.0f,
                         0.0f,     0.0f,    0.0f,   1.0f };
    bob = variable;
}

cmath库中的cossin接受双精度作为参数。警告试图告诉您您正在给它一个float,它必须将其转换为double

函数的std版本是重载的,但是如果要使用它们,则必须像这样使用它们的命名空间调用它们std::cos