Два розповсюджені випадки:
Ціла арифметика
Очевидно, що якщо ви використовуєте цілу арифметику (яка скорочується), ви отримаєте інший результат. Ось невеликий приклад у C #:
public static void TestIntegerArithmetic()
{
int newValue = 101;
int oldValue = 10;
int SOME_CONSTANT = 10;
if(newValue / oldValue > SOME_CONSTANT)
{
Console.WriteLine("First comparison says it's bigger.");
}
else
{
Console.WriteLine("First comparison says it's not bigger.");
}
if(newValue > oldValue * SOME_CONSTANT)
{
Console.WriteLine("Second comparison says it's bigger.");
}
else
{
Console.WriteLine("Second comparison says it's not bigger.");
}
}
Вихід:
First comparison says it's not bigger.
Second comparison says it's bigger.
Арифметика з плаваючою комою
Окрім того, що поділ може дати інший результат, коли він ділиться на нуль (він створює виняток, тоді як множення не робить), це також може призвести до дещо різних помилок округлення та іншого результату. Простий приклад в C #:
public static void TestFloatingPoint()
{
double newValue = 1;
double oldValue = 3;
double SOME_CONSTANT = 0.33333333333333335;
if(newValue / oldValue >= SOME_CONSTANT)
{
Console.WriteLine("First comparison says it's bigger.");
}
else
{
Console.WriteLine("First comparison says it's not bigger.");
}
if(newValue >= oldValue * SOME_CONSTANT)
{
Console.WriteLine("Second comparison says it's bigger.");
}
else
{
Console.WriteLine("Second comparison says it's not bigger.");
}
}
Вихід:
First comparison says it's not bigger.
Second comparison says it's bigger.
Якщо ви мені не вірите, ось ось Загадка, яку ви можете виконати і побачити самі.
Інші мови можуть бути різними; майте на увазі, однак, що C #, як і багато мов, реалізує бібліотеку з плаваючою точкою стандарту IEEE (IEEE 754) , тому ви повинні отримати ті ж результати в інших стандартизованих часах виконання.
Висновок
Якщо ви працюєте на « зеленому полі» , ви, ймовірно, добре.
Якщо ви працюєте над застарілим кодом, а додаток - це фінансовий або інший чутливий додаток, який виконує арифметику і зобов'язаний забезпечити стійкі результати, будьте дуже обережні, змінюючи операції. Якщо потрібно, будьте впевнені, що у вас є одиничні тести, які дозволять виявити будь-які тонкі зміни в арифметиці.
Якщо ви просто робите такі речі, як підрахунок елементів у масиві чи інші загальні обчислювальні функції, вам, ймовірно, буде гаразд. Я не впевнений, що метод множення робить ваш код яснішим.
Якщо ви реалізуєте алгоритм до специфікації, я б нічого не змінив, не тільки через проблему помилок округлення, але щоб розробники могли переглянути код і перенести кожен вираз назад у специфікацію, щоб переконатися у відсутності реалізації недоліки.
oldValue >= 0
?