??Оператор (C #) для двойного возвращает неверный результат - PullRequest
0 голосов
/ 10 октября 2018

Используя C #, можно понять, почему следующий метод возвращает 57.999999999999993 (вместо 58 )?

double Test_Null_Coalescing_Operator()
{
    double? x = 0.58;
    return ((x ?? 0) * 100);
}

//returns 57.999999999999993 (instead of 58)

Ответы [ 4 ]

0 голосов
/ 10 октября 2018

Ответы и связанные дубликаты объясняют причину, я просто хочу выделить практическое правило.Если уместно десятичное записанное представление числа, используйте тип decimal.Типы float и double быстры, поскольку они непосредственно поддерживаются процессором, но используют их только в том случае, если их десятичное представление не имеет значения (например, рендеринг, обработка мультимедиа и т. Д.).

Во многихВ языках decimal (или аналогичный десятичный тип с плавающей точкой для той же цели) называется money , что говорит о том, что это то, что вы должны использовать для финансовых расчетов.И на самом деле это то, откуда * C 1013 * приходит постфикс decimal (var x = 0.58m).

0 голосов
/ 10 октября 2018

Предполагая, что double - это 64-битная двоичная с плавающей запятой IEEE 754, 0.58 не совсем представимо.Ближайший - 0.57999999999999996003197111349436454474925994873046875.После умножения на 100, ошибка округления на округление до 58 будет 3.99680288865056354552507400512695312500E-15, который немного больше, чем ошибка округления на округление до 57.99999999999999289457264239899814128875732421875, 3.10862446895043831318616867065429687500E-15

Если вы представляющие физические величинынапример, длина, погрешность измерения полностью превзойдет погрешность округления, меньше чем одна часть в 10 15 .

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

0 голосов
/ 10 октября 2018

@ Фелипе Девеза уже упоминал о причине.Если вы хотите получить точно 0,58, вы можете использовать Math.Round ()

0 голосов
/ 10 октября 2018
...