2010-07-22 4 views
0

Есть ли способ в C++, чтобы он оценивал каждую операцию с плавающей запятой как double, даже если аргументы являются int? У меня есть программа и множество мест, где у меня есть код, такой как 1/2, 5/6. В этих случаях C++ выводит результат на int, что затягивает весь расчет. С точки зрения финансовых вычислений, есть другие библиотеки, кроме «cmath», которые я мог бы использовать, которые будут содержать более сложные функции.Арифметические операции на C++ в плавающей точке

+0

Он не «передает результат в int», он выполняет операцию с целыми числами, что может привести только к целочисленному результату (регистры не могут даже содержать поплавки). Если вам нужен вывод с плавающей запятой, вам нужно выполнить операцию над поплавками, как [Джеймс Макнеллис сказал] (http://stackoverflow.com/questions/3305682/c-arithmetic-operations-in-floating-point/3305688 # 3305688) –

+0

Если вы собираетесь использовать вычисления с плавающей точкой для финансовых вычислений, убедитесь, что вы знаете, что вы делаете (см .: ошибка округления). –

ответ

4

В C (и, следовательно, C++) все встроенные операторы (т.е. POD) работают на объектах same type. Таким образом, если параметры встроенного оператора имеют разные типы, то компилятор будет неявно использовать один (обычно) из них (в соответствии с четко определенными правилами), чтобы они были одинаковыми. Результат оператора также тот же тип, что и входные параметры.

Что вы видите, это целочисленное деление, которое возвращает целое число.

Неявные правила литья:

1) If either value is long double then cast the other to long doubele (technically only C) 
2) If either value is  double then cast the other to  double 
3) If either value is  float then cast the other to  float 
4) If either value is unsi long then cast the other to unsi long 
5) If either value is  long then cast the other to  long 
6) If either value is unsi int then cast the other to unsi int 
7) Cast both values to int 

Примечание: Все arithmatic операции выполняются по крайней мере, междунар. Это означает, что если оба параметра являются (u) короткими и/или char, то оба они передаются в int.

Из этого можно видеть, что для того, чтобы операция выполнялась в двухместных, по крайней мере один из параметров должен быть двойным в коде. Для этого просто добавьте дробную часть в выражение.

int val = 1.0/2; 

// This is equivalent to: 

int val = static_cast<int>(1.0/static_cast<double>(2)); 
// Are you not glad the compiler does the implicit cast for you :-) 
3

В этих случаях C++ преобразует результат к междунар, что щурит весь расчет

Нет, в этих случаях, поскольку оба операнда являются целыми числами явно выполняет целочисленное деление; кастинг вообще не происходит.

Правильный ответ будет выполнять деление с плавающей точкой:

1.0/2 

Это не что гораздо больше усилий, чтобы написать десятичную точку, это?

+0

Я никогда не знал, что вы можете просто добавить десятичную дробь без каких-либо дробных цифр; это удобно –

+1

Это может быть немного легче читать, если вы добавите 0, чтобы сделать это 1.0 –

+1

@Martin: Я пытался показать, что один дополнительный персонаж был не намного больше работы. Но вы правы, конечно; его гораздо легче читать как «1.0». –

1

Martin York имеет хорошее объяснение того, что происходит, и James McNellis дает достойный ответ на то, что делать, если вы используете литералы.

Если вы используете вместо этого int//etc переменные, то вы можете обойти это, просто набросив их в линию. например

double Average(int *values, int count) 
{ 
    int sum = 0; 
    for(int i = 0; i < count; ++i) sum += values[i]; 
    return sum/(double) count; // Cast one of the values to double, that will force both to be calculated as doubles 
    // note that "return (double)sum/count;" won't work because operator precendence 
    // causes this to translate to "return (double)(sum/count);" 

    // the "c++ way" to do this would be through the static_cast operator 
    // i.e. "return static_cast<double>(sum)/count;" 
    // or "return sum/static_cast<double>(count);" 
    // both of which are very explicit in what you are casting 
} 
+0

Мне не нравится, что оператор кастинга используется повсюду. В моем случае это сделает код невозможным для чтения и looong строк. – user236215

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