C # и многие другие языки используют IEEE 754 в качестве спецификации для своих типов данных с плавающей точкой. Числа с плавающей запятой выражаются в виде значения и экспоненты, аналогично тому, как десятичное число в научной записи выражается как
1.234567890 x 10^12
^ ^
mantissa exponent
Я не буду вдаваться в подробности (статья в Википедии разбирается в этом лучше, чем я), но IEEE 754 указывает, что :
для 32-разрядного числа с плавающей запятой, такого как тип данных C # float
, имеет 24-битную точность для значимости и 8-битную для показателя степени.
для 64-битного числа с плавающей запятой, такого как тип данных C # double
, имеет 53 бита для значимости и 11 бит для показателя степени.
Поскольку float
имеет только 24 бит точности, он может выражать только 7-8 цифр точности. И наоборот, double
имеет точность 53 бит , поэтому имеет точность 15-16 цифр точности.
Как было сказано в комментариях, если вы не хотите терять точность, не переходите от double
(всего 64 бита) к float
(всего 32 бита). В зависимости от вашего приложения вы, возможно, можете использовать тип данных decimal
, который имеет 28-29 десятичных цифр точности, но будет иметь штрафы, потому что (a) вычисления с ним медленнее, чем для double
или float
, и (b) обычно он гораздо меньше поддерживается внешними библиотеками.
Обратите внимание, что вы говорите о 91.15149709518846
, который на самом деле будет интерпретироваться компилятором как 91.1514970951884
- см., Например, this :
double value = 91.151497095188446;
Console.WriteLine(value);
// prints 91.1514970951884