Стандартные строки формата чисел C# Печать
Добавил(а) microsin   

К сожалению, строки формата C# и принцип их использования несколько отличаются от привычных стандартных строк формата языков C и C++, что вносит немало путаницы. Стандартные строки формата преобразования чисел в текст имеют форму Axx, где:

A одна буква (не цифра) латинского алфавита, которая называется спецификатором (format specifier). Любая числовая строка формата, которая содержит больше одного символа алфавита, включая пробел, интерпретируется как пользовательская строка числового формата (подробнее см. [2]).

xx это опциональное (не обязательное) число, которое называется спецификатором точности (precision specifier). Спецификатор точности указывается в диапазоне от 0 до 99, и он влияет на количество цифр в результате преобразования. Обратите внимание, что спецификатор точности управляет количеством цифр в строковом представлении числа. Он не округляет число сам по себе. Чтобы выполнить операцию округления, используйте метод Math.Ceiling, Math.Floor или Math.Round.

Когда спецификатор точности управляется количеством цифр дробной части в строке результата, результирующая строка отражает количество цифр, которые округлены от нуля (т. е. используется MidpointRounding.AwayFromZero, принцип работы MidpointRounding показан во врезке ниже).

// Этот пример демонстрирует метод Math.Round() вместе с перечислением
// MidpointRounding.
using System;
 
class Sample 
{
   public static void Main() 
   {
   decimal result = 0.0m;
   decimal posValue =  3.45m;
   decimal negValue = -3.45m;
 
// По умолчанию округление положительного и отрицательного значения осуществляется
// к ближайшему четному числу (ToEven). Точность результата 1 десятичная позиция.
    result = Math.Round(posValue, 1);
    Console.WriteLine("{0,4} = Math.Round({1,5}, 1)", result, posValue);
    result = Math.Round(negValue, 1);
    Console.WriteLine("{0,4} = Math.Round({1,5}, 1)", result, negValue);
    Console.WriteLine();
 
// Округление положительного значения к ближайшему четному числу (ToEven), затем
// к ближайшему числу от нуля (AwayFromZero).// Точность результата 1 десятичная позиция.
    result = Math.Round(posValue, 1, MidpointRounding.ToEven);
    Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.ToEven)",
                                          result, posValue);
    result = Math.Round(posValue, 1, MidpointRounding.AwayFromZero);
    Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.AwayFromZero)",
                                          result, posValue);
    Console.WriteLine();
 
// Округление отрицательного числа к ближайшему четному числу (ToEven), затем
// к ближайшему числу от нуля (AwayFromZero).
// Точность результата 1 десятичная позиция.
    result = Math.Round(negValue, 1, MidpointRounding.ToEven);
    Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.ToEven)",
                                          result, negValue);
    result = Math.Round(negValue, 1, MidpointRounding.AwayFromZero);
    Console.WriteLine("{0,4} = Math.Round({1,5}, 1, MidpointRounding.AwayFromZero)",
                                          result, negValue);
    Console.WriteLine();
    }
}

Этот код выведет следующее:

 3.4 = Math.Round( 3.45, 1)
-3.4 = Math.Round(-3.45, 1)
 
 3.4 = Math.Round( 3.45, 1, MidpointRounding.ToEven)
 3.5 = Math.Round( 3.45, 1, MidpointRounding.AwayFromZero)
 
-3.4 = Math.Round(-3.45, 1, MidpointRounding.ToEven)
-3.5 = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero)

Используйте MidpointRounding с подходящей перезагрузкой Math.Round, чтобы предоставить больше управления процессом округления.

Операция округления берет оригинальное число с неявно или явно указанной точностью (precision). Проверяется следующая цифра, которая находится в позиции precision+1, и возвращается ближайшее число с той же точностью, что и оригинальное число. Для положительных чисел: если следующая цифра находится в диапазоне от 0 до 4, то ближайшее число находится в сторону отрицательной бесконечности. Если следующая цифра находится в диапазоне от 6 до 9, то ближайшее число находится в сторону положительной бесконечности. Для отрицательных чисел: если следующая цифра находится в диапазоне от 0 до 4, то ближайшее число находится в сторону положительной бесконечности. Если следующая цифра находится в диапазоне от 6 до 9, то ближайшее число находится в сторону отрицательной бесконечности.

В предыдущих случаях перечисление MidpointRounding не влияет на результат операции округления. Однако если следующая цифра 5, что случай средней точки между двух возможных результатов, и все остальные цифры нулевые или больше нет цифр, то выбор самого близкого числа неоднозначен. В этом случае перечисление MidpointRounding позволяет Вам указать, возвратит ли операция округления ближайшее целое от нуля, или ближайшее четное число.

Следующая таблица демонстрирует результаты округления нескольких отрицательных и положительных чисел совместно с значениями MidpointRounding. Точность, используемая для округления чисел в этой таблице, равна 0, что означает количество цифр после запятой после операции округления. Например, для числа -2.5, одна цифра после запятой, это 5. Из-за того, что эта цифра находится в средней точке для округления, Вы можете использовать значение MidpointRounding, чтобы определить результат округления: -2 или -3, если точность округления 0) Если указано AwayFromZero, то округление вернет -3, потому что это число ближе всего при уходе от нуля. Если указано ToEven, то будет возвращено -2, потому что это ближайшее четное число.

Округляемое число AwayFromZero ToEven
3.5 4 4
2.8 3 3
2.5 3 2
2.1 2 2
-2.1 -2 -2
-2.5 -3 -2
-2.8 -3 -3
-3.5 -4 -4

Примечание: спецификатор точности определяет количество цифр в результирующей строке. Чтобы дополнить строку результата начальными или завершающими пробелами, используйте функцию композитного форматирования [3], и определите компонент выравнивания в элементе формата.

Стандартные строки числового формата поддерживаются следующими функциями:

• Некоторыми перезагрузками метода ToString всех числовых типов. Например, Вы можете предоставить строку числового формата для методов Int32.ToString(String) и Int32.ToString(String, IFormatProvider).
• Возможность композитного форматирования .NET [3], которая используется некоторыми методами Write и WriteLine классов Console и StreamWriter, методом String.Format и методом StringBuilder.AppendFormat. Фича композитного формата позволяет Вам включить строковое представление нескольких элементов данных в одну строку, чтобы указать ширину поля и числа выравнивания в поле. Подробнее см. [3].
• Интерполированными строками в C# и Visual Basic, которые предоставляет упрощенный синтаксис в сравнении со строками композитного формата.

Совет: Вы можете загрузить утилиту форматирования [4], которая позволит Вам применить строки формата либо к числовым значениям, либо к значениям даты и времени, и увидеть строку результата преобразования.

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

Спецификатор
формата
Имя Описание Примеры                             
"C" или "c" Currency Результат: значение валюты. Поддерживает все числовые типы. Спецификатор точности задает количество десятичных цифр после запятой. Спецификатор точности по умолчанию определяется NumberFormatInfo.CurrencyDecimalDigits. 123.456 ("C", en-US)
-> $123.46

123.456 ("C", fr-FR)
-> 123,46 €

123.456 ("C", ja-JP)
-> ¥123

-123.456 ("C3", en-US)
-> ($123.456)

-123.456 ("C3", fr-FR)
-> -123,456 €

-123.456 ("C3", ja-JP)
-> -¥123.456
"D" или "d" Decimal Результат: цифры целого числа с опциональным знаком. Поддерживает только целочисленные типы. Спецификатор точности задает минимальное количество цифр. Спецификатор точности по умолчанию задает минимальное количество требуемых цифр. 1234 ("D")
-> 1234

-1234 ("D6")
-> -001234
"E" или "e" Exponential (научное представление) Результат: число в экспоненциальном представлении. Поддерживает все типы. Спецификатор точности задает количество десятичных цифр после запятой. Спецификатор точности по умолчанию 6. 1052.0329112756 ("E", en-US)
-> 1.052033E+003

1052.0329112756 ("e", fr-FR)
-> 1,052033e+003

-1052.0329112756 ("e2", en-US)
-> -1.05e+003

-1052.0329112756 ("E2", fr_FR)
-> -1,05E+003
"F" или "f" Fixed-point Результат: целая часть числа, точка и цифры после запятой с опциональным отрицательным знаком. Поддерживает все числовые типы. Спецификатор точности задает количество десятичных цифр после запятой. Спецификатор точности по умолчанию определяется NumberFormatInfo.NumberDecimalDigits. 1234.567 ("F", en-US)
-> 1234.57

1234.567 ("F", de-DE)
-> 1234,57

1234 ("F1", en-US)
-> 1234.0

1234 ("F1", de-DE)
-> 1234,0

-1234.56 ("F4", en-US)
-> -1234.5600

-1234.56 ("F4", de-DE)
-> -1234,5600
"G" или "g" General Результат: более компактное представление либо в виде фиксированной точки, либо в научном виде. Поддерживает все числовые типы. Спецификатор точности задает количество значащих цифр. Спецификатор точности по умолчанию зависит от числового типа. -123.456 ("G", en-US)
-> -123.456

-123.456 ("G", sv-SE)
-> -123,456

123.4546 ("G4", en-US)
-> 123.5

123.4546 ("G4", sv-SE)
-> 123,5

-1.234567890e-25 ("G", en-US)
-> -1.23456789E-25

-1.234567890e-25 ("G", sv-SE)
-> -1,23456789E-25
"N" или "n" Number Результат: целые числа и числа после запятой, с разделением на группы сепаратором, с опциональным знаком отрицательного числа. Поддерживает все числовые типы. Спецификатор точности задает количество позиций десятичных цифр после запятой. Спецификатор точности по умолчанию определяется NumberFormatInfo.NumberDecimalDigits. 1234.567 ("N", en-US)
-> 1,234.57

1234.567 ("N", ru-RU)
-> 1 234,57

1234 ("N1", en-US)
-> 1,234.0

1234 ("N1", ru-RU)
-> 1 234,0

-1234.56 ("N3", en-US)
-> -1,234.560

-1234.56 ("N3", ru-RU)
-> -1 234,560
"P" или "p" Percent Результат: число, умноженное на 100, и отображенное с символом процента. Поддерживает все числовые типы. Спецификатор точности задает количество цифр после запятой. Спецификатор точности по умолчанию определяется NumberFormatInfo.PercentDecimalDigits. 1 ("P", en-US)
-> 100.00 %

1 ("P", fr-FR)
-> 100,00 %

-0.39678 ("P1", en-US)
-> -39.7 %

-0.39678 ("P1", fr-FR)
-> -39,7 %
"R" или "r" Round-trip Результат: строка, которая может быть преобразована обратно в то же самое число. Поддерживает типы Single, Double и BigInteger. Замечание: рекомендуется использовать только для типа BigInteger. Для Double используйте "G17", для Single используйте "G9". Спецификатор точности игнорируется. 123456789.12345678 ("R")
-> 123456789.12345678

-1234567890.12345678 ("R")
-> -1234567890.1234567
"X" или "x" Hexadecimal Результат: строка шестнадцатеричных символов. Поддерживает только целочисленные типы. Спецификатор точности задает количество цифр в строке результата. 255 ("X")
-> FF

-1 ("x")
-> ff

255 ("x4")
-> 00ff

-1 ("X4")
-> 00FF
Любой другой одиночный символ Неизвестный спецификатор Приведет к выбрасыванию исключения FormatException во время работы программы (runtime).  

[Использование строк стандартного числового форматирования]

Стандартные строки формата чисел могут использоваться для форматирования числового значения одним из двух способов:

• Они могут быть переданы в перезагрузку метода ToString, у которой есть спецификатор формата. Следующий пример форматирует числовое значение как строка валюты (currency) с текущей используемой страной (culture). Здесь в примере это культура en-US.

decimal value = 123.456m;
Console.WriteLine(value.ToString("C2"));
// Отобразит $123.46

• Они могут быть предоставлены как аргумент formatString в элементе формата, используемым с такими методами, как String.Format, Console.WriteLine и StringBuilder.AppendFormat. Для дополнительной информации см. [3]. Следующий пример показывает элемент формата для вставки в строку значения валюты.

decimal value = 123.456m;
Console.WriteLine("Баланс Вашего счета {0:C2}.", value);
// Отобразит "Баланс Вашего счета $123.46."

Опционально Вы можете предоставить аргумент выравнивания, чтобы указать ширину поля чисел, и как оно должно быть выровнено - вправо или влево. Следующий пример показывает левое выравнивание поля из 28 символов, и правое выравнивание значения валюты в поле из 14 символов.

decimal[] amounts = { 16305.32m, 18794.16m };
Console.WriteLine("   Начальный баланс           Конечный баланс");
Console.WriteLine("   {0,-28:C2}{1,14:C2}", amounts[0], amounts[1]);
// Отобразит:
//        Начальный баланс           Конечный баланс
//        $16,305.32                      $18,794.16

Следующие врезки предоставляют подробную информацию по каждой стандартной строке числового формата.

Спецификатор валюты "C" (от слова currency, валюта) преобразует число в строку, представляющую количество денег. Спецификатор точности показывает желаемое количество позиций цифр в строке результата преобразования. Если спецификатор точности опущен, то точность по умолчанию определяется свойством NumberFormatInfo.CurrencyDecimalDigits.

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

На строку результата влияет информация форматирования текущего объекта NumberFormatInfo. Следующая таблица перечисляет свойства NumberFormatInfo, которые управляют форматирование возвращаемой строки.

Свойство NumberFormatInfo Описание
CurrencyPositivePattern Определяет размещение символа валюты для положительных значений.
CurrencyNegativePattern Определяет размещение символа валюты для отрицательных значений, и определяет, представлен ли знак минус круглыми скобками или свойством NegativeSign.
NegativeSign Определяет использование знака минус, если CurrencyNegativePattern показывает, что круглые скобки не используются.
CurrencySymbol Определяет символ валюты.
CurrencyDecimalDigits Определяет количество цифр после запятой для значения валюты. Это значение может быть переназначено использованием спецификатора точности.
CurrencyDecimalSeparator Определяет строку, которая отделяет целую часть и часть после запятой.
CurrencyGroupSeparator Определяет строку, которая разделяет группы цифр целой части.
CurrencyGroupSizes Определяет количество цифр целой части, которое появляется в группе.

Следующий пример форматирует значение Double [7] со спецификатором валюты.

double value = 12345.6789;
Console.WriteLine(value.ToString("C", CultureInfo.CurrentCulture));
Console.WriteLine(value.ToString("C3", CultureInfo.CurrentCulture));
Console.WriteLine(value.ToString("C3", 
                  CultureInfo.CreateSpecificCulture("da-DK")));
// Пример отобразит следующий вывод на системе, где текущая культура
// установлена в English (United States, США):
//       $12,345.68
//       $12,345.679
//       kr 12.345,679

Спецификатор формата десятичного числа "D" (от decimal) преобразует число в строку десятичных цифр (0-9), с префиксом знака минус, если число отрицательное. Этот формат поддерживается только для целочисленных типов.

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

На строку результата влияет информация форматирования текущего объекта NumberFormatInfo. Как показывает следующая таблица, одно свойство влияет на форматирование строки.

Свойство NumberFormatInfo Описание
NegativeSign Определяет строку, которая показывает, что число отрицательное.

Следующий пример форматирует значение Int32 с десятичным спецификатором формата.

int value;
 
value = 12345;
Console.WriteLine(value.ToString("D"));
// Отобразит 12345
Console.WriteLine(value.ToString("D8"));
// Отобразит 00012345
 
value = -12345;
Console.WriteLine(value.ToString("D"));
// Отобразит -12345
Console.WriteLine(value.ToString("D8"));
// Отобразит -00012345

Экспоненциальный спецификатор формата ("E", от слова exponential) преобразует число в строку формы "-d.ddd...E+ddd" или "-d.ddd...e+ddd", где каждая буква "d" показывает цифру (0-9). Строка начинается со знака минус, если число отрицательное. Десятичной точке всегда предшествует одна цифра.

Спецификатор точности (precision specifier) показывает желаемое количество цифр после десятичной точки. Если спецификатор точности опущен, то по умолчанию используется 6 цифр после десятичной точки.

Регистр спецификатора формата показывает, какой должен быть префикс экспоненты, "E" или "e". Экспонента всегда состоит из символа плюса или минуса, и минимум трех цифр. Если необходимо, то экспонента добавляется нулями, чтобы удовлетворить этому минимуму.

На строку результата влияет информация форматирования текущего объекта NumberFormatInfo. В следующей таблице перечислены свойства NumberFormatInfo, которые управляют форматированием возвращаемой строки.

Свойство NumberFormatInfo Описание
NegativeSign Определяет строку, которая показывает, что число отрицательное (и для коэффициента, и для экспоненты).
NumberDecimalSeparator Определяет строку, которая в коэффициенте разделяет цифры целой части от цифр после запятой.
PositiveSign Определяет строку, которая показывает, что экспонента положительная.

Следующий пример форматирует значение Double в экспоненциальном формате.

double value = 12345.6789;
 
Console.WriteLine(value.ToString("E", CultureInfo.InvariantCulture));
// Отобразит 1.234568E+004
 
Console.WriteLine(value.ToString("E10", CultureInfo.InvariantCulture));
// Отобразит 1.2345678900E+004
 
Console.WriteLine(value.ToString("e4", CultureInfo.InvariantCulture));
// Отобразит 1.2346e+004
 
Console.WriteLine(value.ToString("E", 
                  CultureInfo.CreateSpecificCulture("fr-FR")));
// Отобразит 1,234568E+004

Спецификатор формата фиксированной точки ("F", от слова fixed-point) преобразует число в строку вида "-ddd.ddd...", где каждый символ "d" показывает число (0-9). Строка начинается со знака минус, если число отрицательное.

Спецификатор точности (precision specifier) показывает желаемое количество позиций десятичных цифр. Если спецификатор формата опущен, то текущее свойство NumberFormatInfo.NumberDecimalDigits предоставляет точность.

На строку результата влияет информация форматирования текущего объекта NumberFormatInfo. В следующей таблице перечислены свойства NumberFormatInfo, которые управляют форматированием возвращаемой строки.

Свойство NumberFormatInfo Описание
NegativeSign Определяет строку, которая показывает, что число отрицательное.
NumberDecimalSeparator Определяет строку, которая разделяет цифры целой части от цифр после запятой.
NumberDecimalDigits Определяет количество по умолчанию цифр после запятой. Это значение может быть переопределено использованием спецификатора точности.

Следующий пример форматирует значение Double и Int32 со спецификатором формата фиксированной точки.

int integerNumber;
integerNumber = 17843;
Console.WriteLine(integerNumber.ToString("F", 
                  CultureInfo.InvariantCulture));
// Отобразит 17843.00
 
integerNumber = -29541;
Console.WriteLine(integerNumber.ToString("F3", 
                  CultureInfo.InvariantCulture));
// Отобразит -29541.000
 
double doubleNumber;
doubleNumber = 18934.1879;
Console.WriteLine(doubleNumber.ToString("F", CultureInfo.InvariantCulture));
// Отобразит 18934.19
Console.WriteLine(doubleNumber.ToString("F0", CultureInfo.InvariantCulture));
// Отобразит 18934
doubleNumber = -1898300.1987;
Console.WriteLine(doubleNumber.ToString("F1", CultureInfo.InvariantCulture));
// Отобразит -1898300.2
Console.WriteLine(doubleNumber.ToString("F3", 
                  CultureInfo.CreateSpecificCulture("es-ES")));
// Отобразит -1898300,199

Спецификатор общего формата "G" (от слова general, общий) преобразует число в более компактное представление, либо с фиксированной точкой, либо с научной нотацией, в зависимости от типа числа и в зависимости от того, присутствует ли спецификатор точности (precision specifier). Спецификатор точности задает максимальное количество значащих цифр, которые появятся в строке результата. Если спецификатор точности опущен, или равен нулю, то тип числа определит точность по умолчанию, как показано в следующей таблице.

Тип числа Точность по умолчанию
Byte или SByte 3 цифры
Int16 или UInt16 5 цифр
Int32 или UInt32 10 цифр
Int64 19 цифр
UInt64 20 цифр
BigInteger Не ограниченная (то же самое, что и для "R")
Single 7 цифр
Double 15 цифр
Decimal 29 цифр

Используется нотация с фиксированной точкой, если экспонента, которая следовала бы из выражения числа в научном представлении, была больше чем -5 и меньше, чем спецификатор точности; иначе используется научная нотация. Результат содержит, если это необходимо, десятичную точку, или завершающие нули после пропущенной десятичной точки. Если присутствует спецификатор точности, и количество значащих цифр в результате превышает указанную точность, лишние завершающие цифру удаляются округлением.

Однако, если число десятичное, и спецификатор точности опущен, то всегда используется нотация с фиксированной точкой, и завершающие нули сохраняются.

Если используется научная нотация, то экспонента в результате снабжается префиксом "E", если спецификатор формата "G", или "e", если спецификатор формата "g". Экспонента содержит минимум 2 цифры. Ото отличается от формата для научной нотации, которое производится с экспоненциальным спецификатором формата, включающим минимум 3 цифры в экспоненте.

Обратите внимание, что когда используется значение Double, спецификатор формата "G17" гарантирует, что оригинальное значение Double успешно пройдет прямое и обратное преобразование (round-trips). Причина в том, что Double совместимо со стандартом IEEE 754-2008 чисел двойной точности (double-precision, binary64) с плавающей запятой, которые дают 17 значащих цифр точности. Рекомендуется использовать вместо спецификатора формата "R" (см. далее), потому что в некоторых случаях "R" не может успешно выполнить прямое и обратное преобразование значений с плавающей точкой двойной точности. Следующий пример иллюстрирует один такой случай.

using System;
 
public class Example
{
   public static void Main()
   {
      double original = 0.84551240822557006;
      var rSpecifier = original.ToString("R");
      var g17Specifier = original.ToString("G17");
      
      var rValue = Double.Parse(rSpecifier);
      var g17Value = Double.Parse(g17Specifier);
      
      Console.WriteLine($"{original:G17} = {rSpecifier} (R): {original.Equals(rValue)}");
      Console.WriteLine($"{original:G17} = {g17Specifier} (G17): {original.Equals(g17Value)}");
   }
}

Пример отобразит следующее:

     0.84551240822557006 = 0.84551240822557: False
     0.84551240822557006 = 0.84551240822557006: True

При использовании со значением Single [6] спецификатор формата "G9" гарантирует, что оригинальное значение Single может быть успешно преобразовано в обе стороны. Это потому, что Single совместимо со стандартом IEEE 754-2008 чисел одинарной точности (single-precision, binary32) с плавающей запятой, которые дают точность 9 значащих цифр. Рекомендуется использовать это вместо спецификатора формата "R" потому что в некоторых случаях "R" не дает правильно выполнить преобразование в обе стороны чисел одинарной точности с плавающей запятой.

На строку результата влияет информация форматирования текущего объекта NumberFormatInfo. В следующей таблице перечислены свойства NumberFormatInfo, которые управляют форматированием возвращаемой строки.

Свойство NumberFormatInfo Описание
NegativeSign Определяет строку, которая показывает, что число отрицательное.
NumberDecimalSeparator Определяет строку, которая разделяет цифры целой части от цифр после запятой.
PositiveSign Определяет строку, которая показывает, что экспонента положительная.

Следующие форматы в качестве примера показывают числа с плавающей точкой с помощью спецификатора общего формата.

double number;
 
number = 12345.6789;      
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Отобразит  12345.6789
Console.WriteLine(number.ToString("G", 
                  CultureInfo.CreateSpecificCulture("fr-FR")));
// Отобразит 12345,6789
Console.WriteLine(number.ToString("G7", CultureInfo.InvariantCulture));
// Отобразит 12345.68 
 
number = .0000023;
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Отобразит 2.3E-06       
Console.WriteLine(number.ToString("G", 
                  CultureInfo.CreateSpecificCulture("fr-FR")));
// Отобразит 2,3E-06
 
number = .0023;
Console.WriteLine(number.ToString("G", CultureInfo.InvariantCulture));
// Отобразит 0.0023
 
number = 1234;
Console.WriteLine(number.ToString("G2", CultureInfo.InvariantCulture));
// Отобразит 1.2E+03
 
number = Math.PI;
Console.WriteLine(number.ToString("G5", CultureInfo.InvariantCulture));
// Отобразит 3.1416

Числовой спецификатор формата ("N", от слова numeric) преобразует число в строку формы "-d,ddd,ddd.ddd...", где символ "-" показывает при необходимости отрицательное число, "d" показывает цифру (0-9), "," показывает разделитель группы, и "." показывает символ десятичной точки. Спецификатор точности (precision specifier) показывает желаемое количество цифр после десятичной точки. Если спецификатор точности опущен, If the precision specifier is omitted, the number of decimal places is defined by the current NumberFormatInfo.NumberDecimalDigits property.

На строку результата влияет информация форматирования текущего объекта NumberFormatInfo. В следующей таблице перечислены свойства NumberFormatInfo, которые управляют форматированием возвращаемой строки.

Свойство NumberFormatInfo Описание
NegativeSign Определяет строку, которая показывает, что число отрицательное.
NumberNegativePattern Определяет формат отрицательных значений, и определяет, представлен ли знак минус круглыми скобками или свойством NegativeSign.
NumberGroupSizes Определяет количество цифр целой части числа, появляющееся в группе (между разделителями групп).
NumberGroupSeparator Определяет строку, которая разделяет группы цифр целой части.
NumberDecimalSeparator Определяет строку, которая разделяет цифры целой части от цифр после запятой.
NumberDecimalDigits Определяет значение по умолчанию для количества цифр после запятой. Это значение может быть переопределено использованием спецификатора точности.

Следующий пример форматирует несколько значений с плавающей точкой с помощью спецификатора числового формата.

double dblValue = -12445.6789;
Console.WriteLine(dblValue.ToString("N", CultureInfo.InvariantCulture));
// Отобразит -12,445.68
Console.WriteLine(dblValue.ToString("N1", 
                  CultureInfo.CreateSpecificCulture("sv-SE")));
// Отобразит -12 445,7
 
int intValue = 123456789;
Console.WriteLine(intValue.ToString("N1", CultureInfo.InvariantCulture));
// Отобразит 123,456,789.0

Спецификатор формата процентов ("P") умножает число на 100, и преобразует результат в строку, представляющую проценты. Спецификатор точности (precision specifier) показывает желаемое количество позиций десятичных цифр. Если спецификатор формата опущен, то числовая точность по умолчанию предоставляется используемым текущим свойством PercentDecimalDigits.

В следующей таблице перечислены свойства NumberFormatInfo, которые управляют форматированием возвращаемой строки.

Свойство NumberFormatInfo Описание
PercentPositivePattern Определяет место размещения символа процента для положительных значений.
PercentNegativePattern Определяет место размещения символа процента и символа отрицательного числа для отрицательных значений.
NegativeSign Определяет строку, которая показывает, что число отрицательное.
PercentSymbol Определяет символ процента.
PercentDecimalDigits Определяет количество по умолчанию цифр после запятой в значении процентов. Это может быть переназначено использованием спецификатора точности.
PercentDecimalSeparator Определяет строку, которая отделяет целую часть и дробную часть.
PercentGroupSeparator Определяет строку, которая разделяет группы цифр целой части.
PercentGroupSizes Определяет количество цифр в группе целой части.

Следующий пример форматирует числа с плавающей точкой процентным спецификатором формата.

double number = .2468013;
Console.WriteLine(number.ToString("P", CultureInfo.InvariantCulture));
// Отобразит 24.68 %
Console.WriteLine(number.ToString("P", 
                  CultureInfo.CreateSpecificCulture("hr-HR")));
// Отобразит 24,68%     
Console.WriteLine(number.ToString("P1", CultureInfo.InvariantCulture));
// Отобразит 24.7 %

Спецификатор формата "туда-и-обратно" ("R", от слова round-trip) делает попытку гарантировать, что числовое значение можно преобразовать в текст и обратно без потерь, т. е. должно получится то же самое число. Этот формат поддерживается только для типов Single, Double и BigInteger.

Для значений Double и Single спецификатор формата "R" в некоторых случаях ошибается, так что не получается выполнить принцип "туда и обратно" без потерь, и также показывает относительно невысокую производительность. Поэтому рекомендуется вместо этого использовать для успешного преобразования спецификатор формата "G17" для значений типа Double и спецификатор формата "G9" для значений типа Single.

Когда спецификатором R форматируется значение BigInteger, то строковое значение результата содержит все значащие цифры в значении BigInteger.

Хотя Вы можете добавить спецификатор точности (precision specifier), он все равно будет игнорироваться. Принципу "туда и обратно"Round trips are given precedence over precision when using this specifier.

На строку результата влияет информация форматирования текущего объекта NumberFormatInfo. В следующей таблице перечислены свойства NumberFormatInfo, которые управляют форматированием возвращаемой строки.

Свойство NumberFormatInfo Описание
NegativeSign Определяет строку, которая показывает, что число отрицательное.
NumberDecimalSeparator Определяет строку, которая разделяет цифры целой части от цифр после запятой.
PositiveSign Определяет строку, которая показывает, что экспонента положительная.

Следующий пример форматирует значение BigInteger со спецификатором формата round-trip.

using System;
using System.Numerics;
 
public class Example
{
   public static void Main()
   { 
      var value = BigInteger.Pow(Int64.MaxValue, 2);
      Console.WriteLine(value.ToString("R"));
   }
}

Этот пример отобразит следующее:

      85070591730234615847396907784232501249

Важное замечание: в некоторых случаях значения типа Double, отформатированные стандартным спецификатором "R", не отвечают принципу round-trip, если программа скомпилирована с использованием опций компилятора /platform:x64 или /platform:anycpu, и запущена на 64-битных системах.

Чтобы обойти проблему со значениями Double, отформатированными стандартным форматом "R", Вы можете вместо этого выполнить форматирование значений Double использованием стандартного формата "G17". Следующий пример использует строку формата "R" со значением Double, где видно не соблюдения принципа round-trip, и также показано использование формата "G17" для успешного преобразования с выполнением условия round-trip, когда можно успешно выполнить преобразование к оригинальному значению.

using System;
using System.Globalization;
 
public class Example
{
   static void Main(string[] args)
   {
      Console.WriteLine("Попытка выполнить round-trip преобразование Double с помощью 'R':");
      double initialValue = 0.6822871999174;
      string valueString = initialValue.ToString("R",
                                                 CultureInfo.InvariantCulture);
      double roundTripped = double.Parse(valueString,
                                         CultureInfo.InvariantCulture);
      Console.WriteLine("{0:R} = {1:R}: {2}\n",
                        initialValue, roundTripped, initialValue.Equals(roundTripped));
      Console.WriteLine("Попытка выполнить round-trip преобразование Double с помощью 'G17':");
      string valueString17 = initialValue.ToString("G17",
                                                   CultureInfo.InvariantCulture);
      double roundTripped17 = double.Parse(valueString17,
                                           CultureInfo.InvariantCulture);
      Console.WriteLine("{0:R} = {1:R}: {2}\n",
                        initialValue, roundTripped17, initialValue.Equals(roundTripped17));
   }
}
 
// Если приложение предназначено на любой процессор (anycpu), или на 64-битную
// платформу (x64), и запущено на системе x64, то пример выведет следующее:
//       Попытка выполнить round-trip преобразование Double с помощью 'R':
//       0.6822871999174 = 0.68228719991740006: False
//
//       Попытка выполнить round-trip преобразование Double с помощью 'G17':
//       0.6822871999174 = 0.6822871999174: True

Спецификатор шестнадцатеричного формата ("X", hexadecimal) преобразует число в строку hex-цифр. Для шестнадцатеричных цифр, которые больше 9, будут использоваться алфавитные HEX-цифры в верхнем или нижнем регистре, в зависимости от регистра спецификатора. Например, используйте "X" для генерации символов "ABCDEF", и "x" для генерации "abcdef". Этот формат поддерживается только для целочисленных типов.

Спецификатор формата (precision specifier) показывает минимальное количество цифр, которое желательно иметь в строке результата. Если необходимо, число будет дополнено слева нулями, чтобы сгенерировать количество цифр, указанное спецификатором точности.

На строку результата никак не влияет информация форматирования текущего объекта NumberFormatInfo.

Следующий пример форматирует значения Int32 со спецификатором шестнадцатеричного формата.

int value;
 
value = 0x2045e;
Console.WriteLine(value.ToString("x"));
// Отобразит 2045e
Console.WriteLine(value.ToString("X"));
// Отобразит 2045E
Console.WriteLine(value.ToString("X8"));
// Отобразит 0002045E
 
value = 123456789;
Console.WriteLine(value.ToString("X"));
// Отобразит 75BCD15
Console.WriteLine(value.ToString("X2"));
// Отобразит 75BCD15

[Дополнительные замечания]

Настройки в Панели Управления. Настройки региона и языка (Control Panel -> Regional and Language Options) влияют на строку результата, которая будет сгенерирована операцией форматирования. Эти настройки используются для инициализации объекта NumberFormatInfo, связанного с культурой текущего потока (current culture), что предоставляет значения для управления форматированием. Компьютеры, которые используют разные региональные настройки, сгенерируют разные строки результата.

Дополнительно, если используется конструктор CultureInfo.CultureInfo(String) для инстанциации нового объекта CultureInfo, который представляет ту же культуру, что и текущая системная культура, можно сделать любые подстройки опций региона и языка, отличающиеся от текущих опций Regional и Language панели управления. Вы можете использовать конструктор CultureInfo.CultureInfo(String, Boolean), чтобы создать объект CultureInfo, который не отражает системные настройки.

Свойства NumberFormatInfo. На форматирование влияют свойства текущего объекта NumberFormatInfo, который неявно представляется для культуры текущего потока, или явно параметром IFormatProvider метода, который использует параметр для специального форматирования. Укажите для этого параметра объект NumberFormatInfo или CultureInfo.

Примечание: для информации по настройке шаблонов или строк, используемых в форматировании числовых значений, см. описание класса NumberFormatInfo [8].

Интегральные типы и типы с плавающей запятой. Некоторые описания стандартных спецификаторов числового формата ссылаются на целочисленные (интегральные, integral) типы чисел или типы чисел с плавающей запятой (floating-point). Интегральные типы чисел это Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64 и BigInteger. Типы с плавающей запятой это Decimal, Single и Double.

Бесконечность для плавающей точки и NaN. Независимо от строк формата, если значение типа плавающей точки Single или Double получает положительную бесконечность, отрицательную бесконечность или значение "не число" (not a number, NaN), форматированная строка будет представлять соответствующее значение свойства PositiveInfinitySymbol, NegativeInfinitySymbol или NaNSymbol, которое указано текущим применяемым объектом NumberFormatInfo.

Следующий пример кода C# форматирует интегральное значение и значение с плавающей запятой с использованием культуры en-US и всех стандартных спецификаторов формата числа. Этот пример использует для частных типа чисел (Double и Int32), но должен дать подобные результаты для любых других числовых базовых типов (Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64, BigInteger, Decimal и Single).

using System;
using System.Globalization;
using System.Threading;
 
public class NumericFormats
{
   public static void Main()
   {
      // Отобразит строковые представления чисел для культуры en-us:
      CultureInfo ci = new CultureInfo("en-us");
      
      // Вывод значений с плавающей точкой:
      double floating = 10761.937554;
      Console.WriteLine("C: {0}", 
              floating.ToString("C", ci));           // Отобразит "C: $10,761.94"
      Console.WriteLine("E: {0}", 
              floating.ToString("E03", ci));         // Отобразит "E: 1.076E+004"
      Console.WriteLine("F: {0}", 
              floating.ToString("F04", ci));         // Отобразит "F: 10761.9376"
      Console.WriteLine("G: {0}",  
              floating.ToString("G", ci));           // Отобразит "G: 10761.937554"
      Console.WriteLine("N: {0}", 
              floating.ToString("N03", ci));         // Отобразит "N: 10,761.938"
      Console.WriteLine("P: {0}", 
              (floating/10000).ToString("P02", ci)); // Отобразит "P: 107.62 %"
      Console.WriteLine("R: {0}", 
              floating.ToString("R", ci));           // Отобразит "R: 10761.937554"
      Console.WriteLine();
      
      // Вывод целочисленных (интегральных) значений:
      int integral = 8395;
      Console.WriteLine("C: {0}", 
              integral.ToString("C", ci));           // Отобразит "C: $8,395.00"
      Console.WriteLine("D: {0}", 
              integral.ToString("D6", ci));          // Отобразит "D: 008395" 
      Console.WriteLine("E: {0}", 
              integral.ToString("E03", ci));         // Отобразит "E: 8.395E+003"
      Console.WriteLine("F: {0}", 
              integral.ToString("F01", ci));         // Отобразит "F: 8395.0"    
      Console.WriteLine("G: {0}",  
              integral.ToString("G", ci));           // Отобразит "G: 8395"
      Console.WriteLine("N: {0}", 
              integral.ToString("N01", ci));         // Отобразит "N: 8,395.0"
      Console.WriteLine("P: {0}", 
              (integral/10000.0).ToString("P02", ci)); // Отобразит "P: 83.95 %"
      Console.WriteLine("X: 0x{0}", 
              integral.ToString("X", ci));           // Отобразит "X: 0x20CB"
      Console.WriteLine();
   }
}

[Ссылки]

1. Standard Numeric Format Strings site:docs.microsoft.com.
2. Custom Numeric Format Strings site:docs.microsoft.com.
3. Composite Formatting site:docs.microsoft.com.
4. .NET Framework 4 Formatting Utility site:code.msdn.microsoft.com (NET Framework 4 Formatting Utility.zip).
5. How to: Pad a Number with Leading Zeros site:docs.microsoft.com.
6. Single Struct site:docs.microsoft.com.
7. Double Struct site:docs.microsoft.com.
8. NumberFormatInfo Class site:docs.microsoft.com.