Десятичная ошибка преобразования ToString() в С#
У меня возникла проблема, когда я пытаюсь преобразовать decimal?
в string
. Сценарий
decimal decimalValue = .1211;
string value = (decimalValue * 100).ToString();
Текущий результат: value = 12.1100
Ожидаемый результат: value = 12.11
Пожалуйста, дайте мне знать, что может быть причиной этого.
Ответы
Ответ 1
Decimal
сохраняет любые конечные нули в числе Decimal
. Если вы хотите вместо двух десятичных знаков:
decimal? decimalValue = .1211m;
string value = ((decimal)(decimalValue * 100)).ToString("#.##")
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
или
string value = ((decimal)(decimalValue * 100)).ToString("N2")
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
Из System.Decimal
:
Десятичное число является плавающей точкой значение, которое состоит из знака, числовое значение, где каждая цифра в значение находится в диапазоне от 0 до 9, а a коэффициент масштабирования, который указывает положение плавающей десятичной точки который отделяет интеграл и дробные части числового значения.
Двоичное представление десятичной Значение состоит из 1-битового знака, 96-битное целочисленное число и масштабирование фактор, используемый для деления 96-битного целое число и указать, какая часть его является десятичной дробью. Масштабирование фактор неявно равен числу 10, повышен до уровня от 0 до 28. Следовательно, двоичный представление десятичного значения формы ((-2 96 до 2 96)/10 (от 0 до 28)), где -2 96 -1 равно MinValue и 2 96 -1 равно MaxValue.
Масштабный коэффициент также сохраняет любые конечные нули в десятичном числе. Конечные нули не влияют на значение десятичного числа в арифметические операции или операции сравнения. Однако → конечные нули могут быть обнаруженный методом ToString, если соответствующая строка формата применяется <
Примечания:
- десятичное умножение нужно отличить до десятичного, потому что
Nullable<decimal>.ToString
не имеет поставщика формата
-
как сказал Крис, вам нужно обработать случай, когда Nullable<decimal>
равен null
. Один из способов: Null-Coalescing-Operator
:
((decimal)(decimalValue ?? 0 * 100)).ToString("N2")
Эта статья от Джона Скита стоит прочитать:
Десятичная с плавающей запятой в .NET (для сохранения нулей, если вы нетерпеливы)
Ответ 2
Поскольку вы используете Nullable<T>
как ваш decimal
, Nullable<T>.ToString()
, метод не имеет перегрузки, он принимает параметры, которые можно использовать для форматирования.
Вместо этого вы можете явно применить его к decimal
, и вы можете использовать метод .ToString()
для форматирования.
Просто используйте формат "0.00"
в методе .ToString()
.
decimal? decimalValue = .1211M;
string value = ((decimal)(decimalValue * 100)).ToString("0.00");
Console.WriteLine(value);
Выход будет:
12.11
Вот DEMO
.
В качестве альтернативы вы можете использовать Nullable<T>.Value
без какой-либо разговора:
string value = (decimalValue * 100).Value.ToString("0.00");
За дополнительной информацией обращайтесь Custom Numeric Format Strings
Ответ 3
В качестве альтернативы вы можете указать формат "F2", например: string val = decVal.ToString("F2")
, поскольку это указывает на 2 десятичных знака.
Ответ 4
Используйте спецификатор формата с фиксированной точкой ( "F" .
string value = (decimalValue * 100).ToString("F");
Спецификатор точности по умолчанию основан на значении свойства NumberFormatInfo.NumberDecimalDigits, которое по умолчанию имеет значение 2. Поэтому, если не указать цифру aftyer "F", она по умолчанию указывает две десятичные цифры.
F0 - No decimal places
F1 - One decimal place
Ответ 5
String.Format("{0:0.00}", decimalValue * 100);
Вы можете использовать .Format()
в качестве альтернативы .ToString("0.00"
).
Ответ 6
Так как decimal?
не имеет перегрузки ToString(string format)
, проще всего использовать String.Format
вместо этого, который также обеспечит согласованные результаты с тегом null
для decimalValue
(в результате получается пустая строка) по сравнению с исходным кодом:
string value = String.Format("{0:#.##}", decimalValue * 100);
Но есть и другие соображения для других чисел, о которых вы не поняли.
Если у вас есть число, которое не производит значение больше 0, показывает ли он ноль? То есть, для 0.001211
отображается ли оно как 0.12
или .12
? Если вам нужен начальный ноль, используйте это вместо этого (обратите внимание на изменение от #.##
до 0.##
):
string value = String.Format("{0:0.##}", decimalValue * 100);
Если у вас более двух значащих знаков после запятой, вы хотите, чтобы они отображались? Итак, если у вас .12113405
будет отображаться как 12.113405
? Если это так, используйте:
string value = String.Format("{0:#.############}", decimalValue * 100);
(честно говоря, я думаю, что должна быть лучшая строка форматирования, особенно, поскольку она поддерживает только 12 знаков после запятой)
И, конечно, если вы хотите как ведущие нули, так и несколько десятичных знаков, просто соедините два выше:
string value = String.Format("{0:0.############}", decimalValue * 100);
Ответ 7
Если вы не хотите ограничивать определенное количество десятичных цифр:
decimal? decimalValue = .1211;
string value = decimalValue == null
? "0"
: decimalValue == 0
? "0"
: (decimalValue * 100).ToString().TrimEnd('0');
Это обрезает любые (если есть) конечные нули строки, а также возвращает "0", если decimalValue
равно null. Если значение равно 0, то "0" возвращается без обрезки.