代码之家  ›  专栏  ›  技术社区  ›  user980058

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

  •  2
  • user980058  · 技术社区  · 11 年前

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

    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]
    

    这听起来像是在尝试使用“double 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 };
    
    4 回复  |  直到 11 年前
        1
  •  3
  •   Shafik Yaghmour    11 年前

    你需要使用 std::sin std::cos 代替 sin cos 以便您将获得适当重载的版本。你可以看到区别 live :

    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 };
    

    它是 unspecified behavior 函数是否来自 C库 首先在全局命名空间中声明C++草案标准部分 17.6.1.2 页眉 段落 4. 说( 重点矿井 ):

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

    因此,在 C库 函数位于全局命名空间中,您将获得 cos sin 只需要 双重的 这与我们所看到的行为是一致的。

        2
  •  1
  •   Slava    11 年前

    看起来你在使用sin/cos的C verison。如果没有额外的信息,很难说为什么,但修复方法可以是使用C函数sinf/cosf,或者确保std::sin()使用C++函数。

        3
  •  0
  •   yan    11 年前

    编译器抱怨您使用了一个浮点,而它期望得到一个double。您可以显式强制转换每个use,也可以只创建一个局部double。

    我会把你的例子改写如下:

    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;
    }
    
        4
  •  0
  •   Caesar    11 年前

    这个 cos sin cmath 库接受double作为参数。警告是想告诉你,你正在给它一个 float 并且必须将其转换为 double

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