Мне нужно сохранить значения UInt32, Int32 и float внутри переменной. Могу ли я использовать double
без потери информации (например, потерять некоторые цифры в преобразовании) или мне нужно использовать произвольный класс точности?
Из моих текущих исследований, похоже, я могу, так как я могу хранить максимальное значение UInt32 без потери информации:
Assert.AreEqual(UInt32.MaxValue, Convert.ToUInt32(Convert.ToDouble(UInt32.MaxValue)));
Я что-то пропустил?
Возможность хранить максимальное значение UInt32
без потери информации не обязательно означает, что вы сможете хранить все значения в UInt32
без потери информации - в конце концов, существует множество long
значений, которые могут храниться в double
даже если некоторые меньшие значения не могут. (2 62 можно легко сохранить точно в double
, но 2 62 - 1 не могут, например.)
Тем не менее, вы в порядке - мантисса для double
имеет длину в 52 бита, поэтому любое целое число с менее чем 52 битами может быть тривиально сохранено как значение * 2 0 (т.е. эффективный масштаб 0).
И да, значения float
могут быть преобразованы в double
без потери точности.
Однако обратите внимание, что это не означает, что 0.1f == 0.1d
например, это просто означает, что (double) 0.1f
является точно таким же числом, как 0.1f
, в другом представлении.
Также стоит отметить, что Int32
не имеет меньшего диапазона, чем UInt32
- они оба имеют диапазон ровно 2 32 последовательных значения. Однако Int32
имеет меньшее "абсолютное" значение и способ, которым знак представлен в значениях с плавающей запятой, что имеет значение. Вам по-прежнему требуется 32 бита, чтобы сохранить абсолютное значение каждого Int32
, потому что Int32.MinValue
является -10000... 0000 в двоичном формате (всего 32 бита) или - (2 31 + 1).
Наконец, float
не только double
с меньшей точностью - он также получает меньший диапазон. Он имеет только 8 бит для экспоненты по сравнению с 11 в double
. Таким образом, есть числа в пределах диапазона double
которые находятся вне диапазона float
, даже если у них нет значительных (двоичных) цифр.
Decimal
формате: «Этот тип предоставляет методы, которые преобразуют десятичные значения в значения SByte, Int16, Int32, Int64, Byte, UInt16, UInt32 и UInt64 и обратно. Преобразования из этих целочисленных типов в десятичные являются расширяющими преобразованиями. которые никогда не теряют информацию и не создают исключений ".