Стиль программирования в операциях с плавающей точкой - PullRequest
2 голосов
/ 16 декабря 2011

Я сталкиваюсь с некоторыми подобными стилями программирования в основном, когда есть операции Float или Double .

ratio = 1.0 * (top - bottom) / (right - left);  

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

Или это похоже на запись условия, имеющего and 1==1.

PS: Существуют некоторые ситуации, когда в некоторых переменных (кроме коэффициента) присваиваются значения не Float / double как longили целое число.

Ответы [ 3 ]

8 голосов
/ 16 декабря 2011

C / C ++

Если одна или несколько переменных top, bottom и т. Д. Имеют тип double, то умножение на 1.0 не имеет смысла. Вы должны просто удалить его, так как он не имеет смысла. Если все переменные имеют тип float, то умножение на литерал double 1.0 заставляет выражение вычисляться с арифметикой двойной точности.

С другой стороны, когда все переменных являются целыми числами, умножение на 1.0 заставляет выполнять вычисления с арифметикой с плавающей запятой. Без умножения расчет будет выполняться с целочисленной арифметикой, которая даст другой результат.

Я предполагаю, что в коде изначально использовались целые числа, и 1.0 был необходим. В какой-то момент код был изменен для использования переменных с плавающей запятой, но теперь ложное умножение не было удалено.

Delphi

Если вы видели такое выражение в коде Delphi, то вам просто нужно убрать умножение. Наличие оператора деления заставляет выражение быть оцененным как выражение с плавающей запятой.

Правила оценки выражений Delphi немного отличаются от C и C ++. В C и C ++ один символ / используется как для целочисленного деления, так и для деления с плавающей запятой, причем контекст выражения определяет, какая форма деления используется. В Delphi / - это деление с плавающей точкой, а div - целочисленное деление.

3 голосов
/ 16 декабря 2011

В C ++ эмпирическое правило:

Если операция включает в себя плавающий тип, оба операнда преобразуются в плавающий тип (результат имеет плавающий тип)

Имейте в виду, что operation очень связан с operator.И порядок операций определяется приоритетом оператора .

Приоритет основных операций в C ++ вполне естественен по математике:

  • *, / произойдет до +, -
  • выражения внутри (, ) произойдут первыми

Так что если у вас есть

float f = 1.0f + 1 / 2;

// then `f` will be `1.0f`, because

int   sub = 1 / 2     ;  // <- an integer division, happens first and gives 0
float f   = 1.0f + sub;  // <- 0 because the division result was evaluated first

Конечный результат имеет тип float, поскольку последними операциями являются float + int.

Другой пример, включающий выражения в скобках:

float f = (1.0f + 1) / 4;

// `f` will be `0.5` this time. The braced expressions happens first:

float sub = 1.0f + 1;  // float + int = float
float f   = sub / 4;   // float / int = float

Здесь важно отметить, что преобразованиеот 4 до 4.0f происходит до операции, как в этой примерной сборке:

// [mnemomic] [what]+ [target]
fload 1.0f, float_register_0
fload 1,    float_register_1
fadd  float_register_0, float_register_1, float_register_2 // sub is in [2]
fload 4,    float_register_3                               // 4 is in [3]
fdiv  float_register_2, float_register_3, f                // [2]/[3] -> f

Помните

Если операция включает в себя плавающий тип, оба операнда преобразуются в плавающий тип (результат имеет плавающий тип)

1 голос
/ 16 декабря 2011

В C ++ 1.0 - это double, поэтому это повысило бы точность вычислений.Было бы понятнее просто явно привести к double, если это и есть намерение.Это также не идеальное место в выражении, если это намерение (top-bottom будет оцениваться до увеличения точности).

Хотя это может быть гипотетически для дополнительных причин, например, для константыбыть 2.0, но со временем был настроен на 1.0, скрывая первоначальную причину этого умножения.Судя по подсчетам, которые вы выполняете, я не думаю, что это было так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...