Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

4.1.6Типы с плавающей запятой

В C# поддерживается два типа с плавающей запятой: float и double. Типы float и double представляются в 32-разрядном (одинарная точность) или 64-разрядном (двойная точность) формате IEEE 754 и поддерживают следующие наборы значений:

  • Положительный и отрицательный нуль. В большинстве случаев поведение значений положительного и отрицательного нуля совпадает. Различие между ними используется лишь в некоторых операторах (§7.8.2).

  • Положительная и отрицательная бесконечность. Бесконечность может получиться, например, в результате деления ненулевого значения на нуль. К примеру, в результате операции 1.0 / 0.0 получается положительная бесконечность, а в результате операции –1.0 / 0.0 отрицательная.

  • Нечисловые значения зачастую сокращаются как NaN. Значения NaN получаются в результате выполнения недопустимых операций с плавающей запятой, например при делении нуля на нуль.

  • Конечный набор ненулевых значений вида s x m x 2e, где s равно 1 или −1, а значения m и e зависят от конкретного типа с плавающей запятой, выглядит для типа float как 0 < m < 224 и −149 ≤ e ≤ 104, для типа double как 0 < m < 253 и −1075 ≤ e ≤ 970. Допустимыми ненулевыми значениями считаются денормализованные числа с плавающей запятой.

Тип float представляет значения в диапазоне от 1,5 x 10−45 до 3,4 x 1038 (приблизительно) с точностью до 7 знаков.

Тип double представляет значения в диапазоне от 5,0 x 10−324 до 1,7 x 10308 (приблизительно) с точностью до 15–16 знаков.

Если один из операндов бинарного оператора имеет тип с плавающей запятой, второй операнд должен иметь целый тип или тип с плавающей запятой. В этом случае вычисление операции выполняется следующим образом:

  • Если один из операторов имеет целый тип, он преобразуется к типу с плавающей запятой, соответствующему типу второго операнда.

  • В этом случае, если один из операндов имеет тип double, второй операнд преобразуется к типу double. Операция выполняется с применением точности и диапазона, соответствующих типу double. Результат операции имеет тип double (или bool для операторов отношения).

  • В противном случае операция выполняется с применением точности и диапазона, соответствующих типу float. Результат операции имеет тип float (или bool для операторов отношения).

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

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

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

  • Если при выполнении операции с плавающей запятой получается недопустимый результат, операция возвращает результат NaN.

  • Если один или оба операнда операции с плавающей запятой имеют значение NaN, операция возвращает результат NaN.

Операции с плавающей запятой могут выполняться с точностью, превышающей точность типа результата операции. Например, в некоторых аппаратных архитектурах поддерживаются типы с плавающей запятой «extended» или «long double», обладающие расширенными диапазоном и точностью по сравнению с типом double. В таких случаях все операции с плавающей запятой неявно выполняются с использованием типа с более высокой точностью. В таких аппаратных архитектурах операции с плавающей запятой выполняются с меньшей точностью только в целях повышения производительности (в случае ее значительного снижения). Чтобы не допустить одновременного снижения производительности и точности при реализации, в C# возможно применение типа с более высокой точностью для выполнения всех операций с плавающей запятой. Применение таких типов не дает какого-либо измеримого эффекта, за исключением получения более точного результата. Однако в выражениях вида x * y / z, в которых в результате умножения получается значение, выходящее за рамки диапазона типа double, но при последующем делении может быть получен временный результат, принадлежащий диапазону double, вычисление выражения с более высокой точностью позволяет получить определенный результат вместо бесконечности.

4.1.7Тип decimal

Тип decimal представляет собой 128-разрядный тип данных, ориентированный на применение в финансовых и денежных вычислениях. Тип decimal представляет значения в диапазоне от 1,0 x 10−28 до 7,9 x 1028 (приблизительно) с 28–29 значащими цифрами.

Тип decimal определяет конечный набор значений вида (–1)c x10-e, где параметр s может принимать значения 0 или 1, коэффициент c принадлежит диапазону 0 ЎВ c < 296, а значение степени e принадлежит диапазону 0 ЎВ e ЎВ 28. Тип decimal не поддерживает нули и бесконечности со знаками, а также нечисловые значения. Тип decimal представляется в виде 96-разрядного целого числа, умноженного на определенную степень десяти. Значения типа decimal с абсолютной величиной менее 1.0m имеют точность не более 28 десятичных разрядов. Значения типа decimal с абсолютной величиной не менее 1.0m имеют точность 28 или 29 разрядов. В отличие от типов данных float и double, с помощью типа decimal возможно точное представление десятичных дробей, например 0,1. В представлениях float и double такие числа зачастую представляют собой бесконечные дроби, что увеличивает вероятность возникновения ошибок округления.

Если один из операндов бинарного оператора имеет тип decimal, второй операнд должен иметь целочисленный тип или тип decimal. Перед выполнением операции целочисленный операнд (при его наличии) преобразуется к типу decimal.

В результате выполнения операции получается результат типа decimal. Результат определяется путем вычисления точного результата (с сохранением масштаба, определенного для каждого оператора) и последующего округления в соответствии с разрядностью представления. Результат округляется до ближайшего допустимого значения. Если результат одинаково близок к двум допустимым значениям, округление выполняется до значения, в самом младшем разряде которого содержится четное число (так называемое «банковское округление»). Нулевой результат всегда имеет знак 0 и масштаб 0.

Если в результате выполнения арифметической операции с использованием типа decimal получается значение с абсолютной величиной меньшей или равной 5 ×10-29, операция возвращает нуль. Если в результате выполнения арифметической операции с использованием типа decimal получается значение, превышающее допустимое для типа decimal, порождается исключение System.OverflowException.

Тип decimal обеспечивает более высокую точность, однако обладает меньшим диапазоном по сравнению с типами с плавающей запятой. Таким образом, при преобразовании значений, имеющих тип с плавающей запятой, в значение типа decimal возможно возникновение исключений переполнения. При обратном преобразовании возможно снижение точности результата. В связи с этим не существует неявного преобразования между типами с плавающей запятой и типом decimal. Чтобы использовать операнды с плавающей запятой и операнды типа decimal в одном выражении, необходимо выполнить явное приведение их значений.

4.1.8Тип bool

Тип bool представляет логические величины. Тип bool поддерживает два возможных значения: true и false.

Стандартных преобразований между типом bool и другими типами не существует. В частности, тип bool содержит конечное число значений и является отдельным от целых типов. Не допускается использование значений типа bool вместо целочисленных значений и наоборот.

В языках C и C++ нулевые целочисленные значения или значения с плавающей запятой, а также пустые указатели могут быть преобразованы в логическое значение false. Ненулевые целочисленные значения или значения с плавающей запятой и непустые указатели могут быть преобразованы в логическое значение true. В C# такие преобразования выполняются посредством явного сравнения целочисленного значения или значения с плавающей запятой с нулем, а также посредством явного сравнения ссылки на объект со значением null.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]