2013-10-01 6 views
2

по какой-то причине, я получаю следующее предупреждениеплавать, чтобы удвоить неверное истолкование ??? г ++

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 (двойные)» и т.д., а не «с плавающей точкой Cos (с плавающей точкой)» и т.д. Я все время пытаюсь придумать больше способов предложить это компилятору, но я никуда не уйду. Что я могу сделать, чтобы решить эту проблему?

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

Благодаря


Edit: изменить его на это делает предупреждения уйти, но я все еще достаточно знать, что проблема

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

Можете ли вы использовать 'sinf' и' cosf'? – Synxis

ответ

3

Вы должны использовать 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Заголовки пункт говорит (курсив мой):

За исключением случаев, указанных в пунктах с 18 по 30 и приложении D, содержимое каждого заголовка cname должно быть то же, что и соответствующий заголовок name.h, как указано в стандартной библиотеке C (1.2) или в C Unicode TR, в зависимости от ситуации, как если бы это было включено. Однако в стандартной библиотеке C++ декларации (за исключением имен, которые определены как макросы в C) находятся в области пространства имен (3.3.6) пространства имен std. Неизвестно, объявлены ли эти имена впервые в области глобального пространства имен и затем они вводятся в пространство имен std с помощью явных использования-объявлений (7.3.3).

так и в случае, когда C библиотека функции были в глобальном пространстве имен вы будете получать версию cos и sin, что только принимает двойной что согласуется с поведением мы видим.

0

cos и sin в библиотеке cmath принимает двойной параметр. Предупреждение пытается сказать вам, что вы даете ему float и придется преобразовать его к double

версия функций std перегружены, но если вы хотите использовать их, вы должны будете называть их с их пространством имен так std::cos

+2

Они перегружены в C++: http://en.cppreference.com/w/cpp/numeric/math/cos. –

+0

Это не было бы сужающим преобразованием. – juanchopanza

+0

@OliCharlesworth Это правда, но вам нужно будет вызывать «std» версию явно так: 'std :: cos' – Caesar

0

Компилятор жалуется, что вы используете поплавок, где он ожидает двойной. Вы можете либо использовать каждое использование явно, либо просто создать локальный двойной.

Я бы переписать пример следующим образом:

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

Вы также перегрузили версии: http://en.cppreference.com/w/cpp/numeric/ математика/соз – P0W

1

Похоже, вы используете C verison of sin/cos. Трудно сказать, почему без дополнительной информации, но исправить можно было бы использовать функции C sinf/cosf или убедиться, что C++ funcitons используются std :: sin(), например.

Смежные вопросы