что вернет a tostring если int a 0
Why does 0.ToString(«#.##») return an empty string instead of 0.00 or at least 0?
Why does 0.ToString(«#.##») return an empty string? Shouldn’t it be 0.00 or at least 0?
5 Answers 5
# in the string format indicate that the value is optional. If you wish to get the output 0.00 you need the following:
See here for the custom numeric formats that can be passed to this method.
Because in a format string, the # is used to signify an optional character placeholder; it’s only used if needed to represent the number.
If you do this instead: 0.ToString(«0.##»); you get: 0
If you want all three digits: 0.ToString(«0.00»); produces: 0.00
From the comments to this answer, your argument seems to be,
it should show ‘0’, because why would anyone ever want to see an empty string if the numeric value is 0?
The response is simple: You have the choice how you wish it to be displayed. That’s what the custom format strings are for. You have simply chosen the incorrect format string for your needs.
According to the documentation about the Digit Placeholder.
If the value being formatted has a digit in the position where the ‘#’ appears in the format string, then that digit is copied to the result string. Otherwise, nothing is stored in that position in the result string. This specifier never displays the ‘0’ character if it is not a significant digit, even if ‘0’ is the only digit in the string. It will display the ‘0’ character if it is a significant digit in the number being displayed. The «##» format string causes the value to be rounded to the nearest digit preceding the decimal, where rounding away from zero is always used. For example, formatting 34.5 with «##» would result in the value 35.
If you want the zero to display use the Zero PlaceHolder
f the value being formatted has a digit in the position where the ‘0’ appears in the format string, then that digit is copied to the result string. The position of the leftmost ‘0’ before the decimal point and the rightmost ‘0’ after the decimal point determines the range of digits that are always present in the result string.
The «00» specifier causes the value to be rounded to the nearest digit preceding the decimal, where rounding away from zero is always used. For example, formatting 34.5 with «00» would result in the value 35.
toString: Великий и Ужасный
Функция toString в языке JavaScript наверно самая «неявно» обсуждаемая как среди самих js-разработчиков, так и среди внешних наблюдателей. Она — причина многочисленных шуток и мемов про многие подозрительные арифметические операции, преобразования, вводящие в ступор [object Object]‘ы. Уступает, возможно, лишь удивлениям при работе с float64.
Интересные случаи, которые мне приходилось наблюдать, использовать или преодолевать, мотивировали меня написать настоящий разбор полетов. Мы галопом проскочим по спецификации языка и на примерах разберем неочевидные особенности toString.
Если вы ожидаете полезного и достаточного руководства, то вам больше подойдет этот, этот и тот материалы. Если же ваше любопытство все таки преобладает над прагматичностью, то прошу под кат.
Все что нужно знать
Функция toString — свойство объекта-прототипа Object, простыми словами — его метод. Используется при строковом преобразовании объекта и по-хорошему должна возвращать примитивное значение. Свои реализации также имеют объекты-прототипы: Function, Array, String, Boolean, Number, Symbol, Date, RegExp, Error. Если вы реализуете свой объект-прототип (класс), то хорошим тоном будет определить для него и toString.
JavaScript — язык со слабой системой типов: а значит, позволяет нам смешивать разные типы, выполняет многие операции неявно. В преобразованиях toString работает в паре с valueOf, чтобы свести объект к нужному для операции примитиву. Например, оператор сложения оборачивается конкатенацией при наличии среди операторов хотя бы одной строки. Некоторые стандартные функции языка перед своей работой приводят аргумент к строке: parseInt, decodeURI, JSON.parse, btoa и проч.
Про неявное приведение типов сказано и высмеяно уже довольно много. Мы же рассмотрим реализации toString ключевых объектов-прототипов языка.
Object.prototype.toString
Если мы обратимся к соответствующему разделу спецификации, то обнаружим, что основная задача дефолтного toString — это получить так называемый tag для конкатенации в результирующую строку:
Болеющие рефлексией сразу отметят возможность получить тип объекта простой операцией (не рекомендуется спецификацией, но можно):
Особенностью дефолтного toString является то, что он работает с любым значением this. Если это примитив, то он будет приведен к объекту (null и undefined проверяются отдельно). Никаких TypeError:
Как это может пригодиться? Например, при разработке инструментов динамического анализа кода. Имея импровизированный пул используемых в процессе работы приложения переменных, в run-time можно собирать полезную однородную статистику.
У этого подхода есть один существенный недостаток: пользовательские типы. Не трудно догадаться, что для их экземпляров мы просто получим «Object».
Кастомный Symbol.toStringTag и Function.name
ООП в JavaScript базируется на прототипах, а не на классах (как например в Java), и готового метода getClass() у нас нет. Решить возникшую проблему поможет явное определение символа toStringTag для пользовательского типа:
или в прототипном стиле:
Есть альтернативное решение через read-only свойство Function.name, которое пока не является частью спецификации, но поддерживается большинством браузеров. Каждый экземпляр объекта-прототипа/класса имеет ссылку на функцию-конструктор, с помощью которой он был создан. А значит мы можем узнать название типа:
или в прототипном стиле:
Разумеется, это решение не работает для объектов, созданных с помощью анонимной функции («anonymous») или Object.create(null), а также для примитивов без объекта-обертки (null, undefined).
Таким образом, для надежной манипуляции типами переменных стоит комбинировать известные приемы, в первую очередь отталкиваясь от решаемой задачи. В подавляющем большинстве случаев достаточно typeof и instanceof.
Function.prototype.toString
Мы немного отвлеклись, но в результате добрались до функций, у которых есть свой интересный toString. Для начала взглянем на следующий код:
Многие наверно догадались, что это пример куайна. Если загрузить скрипт с таким содержимым в тело страницы, то в консоль будет выведена точная копия исходного кода. Это происходит благодаря вызову toString от функции arguments.callee.
Используемая реализация toString объекта-прототипа Function возвращает строковое представление исходного кода функции, сохраняя используемый при ее определении синтаксис: FunctionDeclaration, FunctionExpression, ClassDeclaration, ArrowFunction и проч.
Например, мы имеем стрелочную функцию:
Вызов bind.toString() вернет нам строковое представление ArrowFunction:
А вызов toString от обернутой функции — это уже строковое представление FunctionExpression:
Этот пример с bind не случаен, так как у нас есть готовое решение с привязкой контекста Function.prototype.bind, и касательно нативных bound functions есть особенность работы Function.prototype.toString с ними. В зависимости от реализации может быть получено представление как самой обернутой функции, так и оборачиваемой (target) функции. V8 и SpiderMonkey последних версий хрома и ff:
Таким образом, стоит проявлять осторожность с нативно-декорируемыми функциями.
Практика использования f.toString
Вариантов использования рассматриваемого toString очень много, но настоятельно только в качестве инструмента метапрограммирования или дебага. Наличие подобного в бизнес-логике типового приложения рано или поздно приведет к неподдерживаемому разбитому корыту.
Самое простое, что приходит на ум — это определение длины функции:
Расположение и количество пробельных символов результата toString отдается спецификацией на откуп конкретной реализации, поэтому для чистоты мы предварительно убираем лишнее, приводя к общему виду. К слову, в старых версиях движка Gecko у функции был специальный параметр indentation, помогающий с форматированием отступов.
Сразу на ум приходит и определение имен параметров функции, что может пригодится для рефлексии:
Это коленочное решение подойдет для синтаксиса FunctionDeclaration и FunctionExpression. Если потребуется более развернутое и точное, то рекомендую обратиться за примерами к исходному коду вашего любимого фреймворка, который наверняка имеет под капотом какое-нибудь внедрение зависимостей, основанное именно на именах объявленных параметров.
Опасный и интересный вариант переопределения функции через eval:
Зная структуру исходной функции, мы создали новую, подменив используемый в ее теле перед аргументами оператор сложения — умножением. В случае программно-генерируемого кода или отсутствия интерфейса расширения функции это может быть волшебным образом полезно. Например, если вы исследуете некоторую математическую модель, подбирая подходящую функцию, играясь с операторами и коэффициентами.
Более практичное использование — это компиляция и дистрибьюция шаблонов. Многие реализации шаблонизаторов компилируют исходный текст шаблона и предоставляют функцию от данных, которая уже формирует конечный HTML (или другое). Далее на примере функции _.template:
А что, если компиляция шаблона требует аппаратных ресурсов или клиент ну очень тонкий? В этом случае мы можем компилировать шаблон на серверной стороне и отдавать клиентам уже не текст шаблона, а строковое представление готовой функции. Тем более, вам не нужно грузить на клиент библиотеку шаблонизатора.
Теперь нам необходимо выполнить этот код на клиенте перед использованием. Чтобы при компиляции не было SyntaxError из-за синтаксиса FunctionExpression:
Или как вам больше нравится. В любом случае:
Это может быть не самая лучшая практика компиляции шаблонов на серверной стороне и их дальнейшего распространения на клиенты. Просто пример с использованием связки Function.prototype.toString и eval.
Наконец, старая задача про определение имени функции (до появления свойства Function.name) через toString:
Разумеется, это хорошо работает в случае синтаксиса FunctionDeclaration. Более интеллектуальное решение потребует хитрого регулярного выражения или использования сопоставления с образцом.
В интернетах полно интересных решений на базе Function.prototype.toString, достаточно лишь поинтересоваться. Делитесь своим опытом в комментариях: очень интересно.
Array.prototype.toString
Реализация toString объекта-прототипа Array является обобщенной и может быть вызвана для любого объекта. Если объект имеет метод join, то результатом toString будет его вызов, иначе — Object.prototype.toString.
Array, логично, имеет метод join, который конкатенирует строковое представление всех своих элементов через переданный в качестве параметра separator (по умолчанию это запятая).
Допустим, нам надо написать функцию, сериализующую список своих аргументов. Если все параметры — примитивы, то во многих случаях мы можем обойтись без JSON.stringify:
Только помните, что строка ’10’ и число 10 будут сериализованы одинаково. В задаче про кратчайший мемоизатор на одном из этапом использовалось это решение.
Нативный джойн элементов массива работает через арифметический цикл от 0 до length и не фильтрует отсутствующие элементы (null и undefined). Вместо этого происходит конкатенация с separator. Это приводит к следующему:
Поэтому, если вы по той или иной причине добавляете в массив элемент с большим индексом (например, это сгенерированный натуральный id), ни в коем случае не джойните и, соответственно, не приводите к строке без предварительной подготовки. Иначе могут быть последствия: Invalid string length, out of memory или просто повисший скрипт. Используйте функции объекта Object values и keys, чтобы итерироваться только по собственным перечислимым свойствам объекта:
Но гораздо лучше избегать подобного обращения с массивом: скорее всего в качестве хранилища вам подошел бы простой key-value объект.
К слову, такая же опасность есть и при сериализации через JSON.stringify. Только еще серьезнее, так как пустые и неподдерживаемые элементы представлены уже как «null»:
Завершая раздел хотелось бы напомнить, что вы можете определить для пользовательского типа свой метод join и вызывать Array.prototype.toString.call в качестве альтернативного приведения к строке, но я сомневаюсь, что это имеет какое-то практическое применение.
Number.prototype.toString и parseInt
Одна из моих любимых задач для js-викторин — Что вернет следующий вызов parseInt?
Первое, что делает parseInt — это неявное приведение аргумента к строке через вызов абстрактной функции ToString, которая в зависимости от типа аргумента выполняет нужную ветку приведения. Для типа number осуществляется следующее:
Я не буду дублировать здесь алгоритм определения предпочтительной формы, только отмечу следующее: если количество цифр числа в десятичной записи превышает 21, то будет выбрана экспоненциальная форма. А это значит, что в нашем случае parseInt работает не с «100. 000» а с «1e30». Поэтому ответ совсем не ожидаемый 2^30. Кто знает природу этого магического числа 21 — пишите!
Далее parseInt смотрит на используемое основание системы счисления radix (по умолчанию 10, у нас — 2) и проверяет символы полученной строки на совместимость с ним. Встретив ‘e’, отсекает весь хвост, оставляя только «1». Результатом же будет целое число, полученное путем перевода из системы с основанием radix в десятичную — в нашем случае, это 1.
Здесь происходит вызов функции toString от объекта-прототипа Number, который использует тот же алгоритм приведения number к строке. Он тоже имеет опциональный параметр radix. Только он бросает RangeError для невалидного значения (должно быть целое от 2 до 36 включительно), тогда как parseInt возвращает NaN.
Стоит помнить о верхней границе системы счисления, если планируете реализовывать экзотическую хэш-функцию: вам может не подойти этот toString.
Задачка, чтобы отвлечься на минутку:
Что вернет и как исправить?
Обделенное вниманием
Мы рассмотрели toString далеко не всех даже нативных объектов-прототипов. Отчасти, потому что лично мне не приходилось попадать с ними в передряги, да и интересного в них не много. Также мы не затронули функцию toLocaleString, так как про нее хорошо бы поговорить отдельно. Если я все таки что-то зря обделил вниманием, упустил из виду или недопонял — обязательно пишите!
Призыв к бездействию
Приведенные мною примеры ни в коем случае не являются готовыми рецептами — только пищей для размышлений. Кроме того я нахожу бессмысленным и немного бестолковым обсуждать подобное на технических собеседованиях: для этого есть вечные темы про замыкания, хойстинг, event loop, паттерны модуль/фасад/медиатор и «конечно» вопросы про [используемый фреймворк].
Настоящая статья получилась сборной солянкой, и я надеюсь вы нашли что-то интересное для себя. PS Язык JavaScript — удивителен!
Бонус
Подготавливая настоящий материал к публикации, я пользовался Google Переводчиком. И совершенно случайно обнаружил занимательный эффект. Если выбрать перевод с русского на английский, ввести «toString» и начать его стирать через клавишу Backspace, то мы будем наблюдать:
Такая вот ирония! Думаю, я далеко не первый такой, но на всякий случай отправил им скриншот со сценарием воспроизведения. Выглядит как безобидный self-XSS, поэтому и делюсь.
Object. To String Метод
Определение
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Возвращает строку, представляющую текущий объект.
Возвращаемое значение
Строка, представляющая текущий объект.
Комментарии
Типы часто переопределяют Object.ToString метод, чтобы предоставить более подходящее строковое представление определенного типа. Типы также часто перегружают Object.ToString метод, чтобы обеспечить поддержку для строк формата или форматирования с учетом языка и региональных параметров.
Метод Object. ToString () по умолчанию
Переопределение метода Object. ToString ()
Категория типа | Переопределяет Object. ToString () | Поведение |
---|---|---|
Класс | Недоступно | Недоступно |
structure | Да ( ValueType.ToString ) | То же, что Object.ToString() |
Перечисление | Да ( Enum.ToString() ) | Имя элемента |
Интерфейс | нет | Недоступно |
Делегат | нет | Недоступно |
Перегрузка метода ToString
В следующем примере метод перегружается ToString для возврата результирующей строки, содержащей значения различных полей Automobile класса. Он определяет четыре строки формата: G, которая возвращает имя модели и год; D, возвращающее имя модели, год и число дверей; C, возвращающее имя модели, год и число цилиндров; и, который возвращает строку со всеми четырьмя значениями полей.
В следующем примере вызывается перегруженный Decimal.ToString(String, IFormatProvider) метод для вывода форматирования значения валюты с учетом языка и региональных параметров.
Дополнительные сведения о строках форматирования и форматировании с учетом языка и региональных параметров см. в разделе Типы форматирования. Строки формата, поддерживаемые числовыми значениями, см. в разделе строки стандартных числовых форматов и строки настраиваемых числовых форматов. Сведения о строках формата, поддерживаемых значениями даты и времени, см. в разделе строки стандартных форматов даты и времени и строки настраиваемых форматов даты и времени.
Расширение метода Object. ToString
Есть несколько вариантов для создания результирующей строки, которая вам нужна.
Если тип является массивом, объектом коллекции или объектом, реализующим IEnumerable IEnumerable интерфейсы или, можно перечислить его элементы с помощью foreach инструкции в C# или For Each. Next конструкции в Visual Basic.
если класс не sealed (в C#) или NotInheritable (в Visual Basic), можно разработать класс-оболочку, который наследует от базового класса, метод которого необходимо Object.ToString настроить. Как минимум, для этого необходимо выполнить следующие действия.
Реализуйте все необходимые конструкторы. Производные классы не наследуют конструкторы базовых классов.
Переопределите Object.ToString метод, чтобы вернуть результирующую строку, которая вам нужна.
В следующем примере определяется класс-оболочка для List класса. Он переопределяет Object.ToString метод для вывода значения каждого метода коллекции, а не полного имени типа.
В следующем примере определяются два метода, расширяющие List класс: ToString2 метод без параметров, а также ToString метод с String параметром, представляющим строку формата.
примечания для среда выполнения Windows
Windows классы среды выполнения, написанные на языке C# или Visual Basic, могут переопределять ToString метод.
среда выполнения Windows и интерфейс IStringable
Если управляемые объекты вызываются машинным кодом или кодом, написанным на языках, таких как JavaScript или C++/CX, они выглядят как реализующие IStringable. Среда CLR автоматически направляет вызовы из IStringable. ToString в, Object.ToString Если IStringable не реализован в управляемом объекте.
так как среда clr auto реализует IStringable для всех управляемых типов в приложениях Windows Store, рекомендуется не предоставлять собственную IStringable реализацию. реализация IStringable может привести к непредвиденному поведению при вызове ToString из среда выполнения Windows, C++/cx или JavaScript.
если вы решили реализовать IStringable в общедоступном управляемом типе, экспортированном в среда выполнения Windows компоненте, применяются следующие ограничения.
Интерфейс IStringable можно определить только в связи «класс реализует» следующим образом:
Невозможно реализовать IStringable в интерфейсе.
Нельзя объявить параметр типа IStringable.
IStringable не может быть типом возвращаемого значения метода, свойства или поля.
Невозможно скрыть реализацию IStringable из базовых классов с помощью определения метода, как показано ниже:
Вместо этого реализация IStringable. ToString должна всегда переопределять реализацию базового класса. Реализацию ToString можно скрыть только путем вызова этого метода в строго типизированном экземпляре класса.
Примечания для тех, кто наследует этот метод
При реализации собственных типов следует переопределить ToString() метод, чтобы он возвращал значения, имеющие смысл для этих типов. Производные классы, которым требуется больший контроль над форматированием, чем ToString() предоставляет, могут реализовывать IFormattable интерфейс. Его ToString(String, IFormatProvider) метод позволяет определять строки формата, управляющие форматированием, и использовать IFormatProvider объект, который может обеспечить форматирование для определенного языка и региональных параметров.
Переопределения ToString() метода должны соответствовать следующим рекомендациям: — Возвращаемая строка должна быть понятной и удобочитаемой для людей.
— Возвращаемая строка должна уникальным образом идентифицировать значение экземпляра объекта.
-Возвращаемая строка должна быть максимально короткой, чтобы ее можно было отображать с помощью отладчика.
ToString() Переопределение не должно возвращать Empty строку или значение null.
ToString() Переопределение не должно вызывать исключение.
— Если строковое представление экземпляра зависит от языка и региональных параметров или может быть отформатировано несколькими способами, реализуйте IFormattable интерфейс.
— Если возвращаемая строка содержит конфиденциальную информацию, необходимо сначала запросить соответствующее разрешение. Если запрос проходит удачно, вы можете вернуть конфиденциальную информацию. в противном случае следует вернуть строку, которая исключается из конфиденциальной информации.
— Если тип реализует метод синтаксического анализа (или Parse TryParse метод, конструктор или какой-либо другой статический метод, который создает экземпляр типа из строки), следует убедиться, что строка, возвращаемая ToString() методом, может быть преобразована в экземпляр объекта.
Int32.To String Метод
Определение
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление.
Перегрузки
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанных сведений об особенностях форматирования для данного языка и региональных параметров.
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанного формата и сведений об особенностях форматирования для данного языка и региональных параметров.
Преобразует числовое значение данного экземпляра в эквивалентное строковое представление с использованием указанного формата.
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление.
ToString(IFormatProvider)
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанных сведений об особенностях форматирования для данного языка и региональных параметров.
Параметры
Объект, предоставляющий сведения о форматировании для определенного языка и региональных параметров.
Возвращаемое значение
Реализации
Примеры
В следующем примере показано строковое представление Int32 значения с помощью CultureInfo объектов, представляющих различные языки и региональные параметры.
Комментарии
ToString(IFormatProvider)Метод форматирует Int32 значение в формате по умолчанию («G» или «общий»), используя NumberFormatInfo объект указанной культуры. Если необходимо указать другой формат или текущий язык и региональные параметры, используйте другие перегрузки ToString метода следующим образом:
Использование формата | Для языка и региональных параметров | Использование перегрузки |
---|---|---|
Формат по умолчанию («G») | Культура по умолчанию (текущий) | ToString() |
Конкретный формат | Культура по умолчанию (текущий) | ToString(String) |
Конкретный формат | Конкретный язык и региональные параметры | ToString(String, IFormatProvider) |
provider Параметр — это объект, реализующий IFormatProvider интерфейс. Его GetFormat метод возвращает NumberFormatInfo объект, предоставляющий сведения о формате строки, возвращаемой этим методом, в зависимости от языка и региональных параметров. Объект, реализующий, IFormatProvider может быть любым из следующих:
CultureInfoОбъект, представляющий язык и региональные параметры, правила форматирования которых будут использоваться.
NumberFormatInfoОбъект, содержащий конкретные сведения о форматировании для этого значения.
Пользовательский объект, реализующий IFormatProvider метод и, GetFormat который возвращает NumberFormatInfo объект, предоставляющий сведения о форматировании.
.NET обеспечивает обширную поддержку форматирования, которая подробно описывается в следующих разделах форматирования:
Дополнительные сведения о спецификаторах числовых форматов см. в разделе строки стандартных числовых форматов и строки настраиваемых числовых форматов.
Дополнительные сведения о форматировании см. в разделе Типы форматирования.
См. также раздел
Применяется к
ToString(String, IFormatProvider)
Преобразует числовое значение данного экземпляра в эквивалентное ему строковое представление с использованием указанного формата и сведений об особенностях форматирования для данного языка и региональных параметров.
Параметры
Стандартная или пользовательская строка числового формата.
Объект, предоставляющий сведения о форматировании для определенного языка и региональных параметров.
Возвращаемое значение
Реализации
Исключения
format является недопустимым или не поддерживается.
Примеры
В следующем примере отображается положительное и отрицательное значение, использующее каждый из поддерживаемых стандартных описателей числового формата для трех различных языков и региональных параметров.
Комментарии
ToString(String, IFormatProvider)Метод форматирует Int32 значение в указанном формате, используя NumberFormatInfo объект указанного языка и региональных параметров. Если вы хотите использовать формат по умолчанию или параметры языка и региональных параметров, используйте другие перегрузки ToString метода следующим образом:
Использование формата | Для языка и региональных параметров | Использование перегрузки |
---|---|---|
Формат по умолчанию («G») | Культура по умолчанию (текущий) | ToString() |
Формат по умолчанию («G») | Конкретный язык и региональные параметры | ToString(IFormatProvider) |
Конкретный формат | Культура по умолчанию (текущий) | ToString(String) |
format Параметр может быть либо стандартной, либо строкой настраиваемого числового формата. Поддерживаются все строки стандартного числового формата, отличные от «R» (или «r»), как и все пользовательские символы числового формата. Если format параметр имеет null значение или является пустой строкой («»), то возвращаемые значения для этого экземпляра форматируются с помощью описателя общего числового формата («G»).
provider Параметр — это объект, реализующий IFormatProvider интерфейс. Его GetFormat метод возвращает NumberFormatInfo объект, предоставляющий сведения о формате строки, возвращаемой этим методом, для определенного языка и региональных параметров. Объект, реализующий, IFormatProvider может быть любым из следующих:
CultureInfoОбъект, представляющий язык и региональные параметры, правила форматирования которых будут использоваться.
NumberFormatInfoОбъект, содержащий конкретные сведения о форматировании для этого значения.
Пользовательский объект, реализующий IFormatProvider метод и, GetFormat который возвращает NumberFormatInfo объект, предоставляющий сведения о форматировании.
.NET обеспечивает обширную поддержку форматирования, которая подробно описывается в следующих разделах форматирования:
Дополнительные сведения о спецификаторах числовых форматов см. в разделе строки стандартных числовых форматов и строки настраиваемых числовых форматов.
Дополнительные сведения о форматировании см. в разделе Типы форматирования.