Округление при преобразовании double в decimal

При достаточно больших значениях double (с заданной целой частью) при его преобразовании в decimal происходит округление. Однако преобразование в long дает правильный результат.

double d = 1725040000979649;
long l = (long)d;
decimal result1 = (decimal)d; // 1725040000979650
decimal result2 = (decimal)l; // 1725040000979649

Почему так происходит? Можно ли как то преобразовать без округления? Пробовал на 3.1 и 8.0 воспроизводить.


Ответы (1 шт):

Автор решения: rotabor

Это какая-то особенность преобразования. 1725040000979649 очень близко к максимальному значению мантиссы для типа Double 179769313486232, и, видимо, дело именно в этом. Если убрать любую цифру, то всё будет норм.

41-45 округляется к 40, 46-49 округляется к 50.

Скорее всего, это сделано потому, что только диапазон 14-тиразрядных чисел может быть представлен точно полностью (до 99 999 999 999 999), поэтому 15-ый рязряд округляется.

Преобразовать без округления можно только так:

decimal result2 = (long)d;
→ Ссылка