Spec-Zone.ru › Ada 2005
Справочник по Ada 2005

G.1.1 Сложные типы

Статическая семантика

В общем пакете библиотек Numerics.Generic_Complex_Types содержится следующее объявление:
generic
type Real is digits <>;
package Ada.Numerics.Generic_Complex_Types is
pragma Pure(Generic_Complex_Types);
type Complex is
record
Re, Im : Real'Base;
end record;
type Imaginary is private;
pragma Preelaborable_Initialization(Imaginary);
i : constant Imaginary;
j : constant Imaginary;
function Re (X : Complex) return Real'Base;
function Im (X : Complex) return Real'Base;
function Im (X : Imaginary) return Real'Base;
procedure Set_Re (X : in out Complex;
Re : in Real'Base);
procedure Set_Im (X : in out Complex;
Im : in Real'Base);
procedure Set_Im (X : out Imaginary;
Im : in Real'Base);
function Compose_From_Cartesian (Re, Im : Real'Base) return Complex;
function Compose_From_Cartesian (Re : Real'Base) return Complex;
function Compose_From_Cartesian (Im : Imaginary) return Complex;
function Modulus (X : Complex) return Real'Base;
function "abs" (Right : Complex) return Real'Base renames Modulus;
function Argument (X : Complex) return Real'Base;
function Argument (X : Complex;
Cycle : Real'Base) return Real'Base;
function Compose_From_Polar (Modulus, Argument : Real'Base)
return Complex;
function Compose_From_Polar (Modulus, Argument, Cycle : Real'Base)
return Complex;
function "+" (Right : Complex) return Complex;
function "-" (Right : Complex) return Complex;
function Conjugate (X : Complex) return Complex;
function "+" (Left, Right : Complex) return Complex;
function "-" (Left, Right : Complex) return Complex;
function "*" (Left, Right : Complex) return Complex;
function "/" (Left, Right : Complex) return Complex;
function "**" (Left : Complex; Right : Integer) return Complex;
function "+" (Right : Imaginary) return Imaginary;
function "-" (Right : Imaginary) return Imaginary;
function Conjugate (X : Imaginary) return Imaginary renames "-";
function "abs" (Right : Imaginary) return Real'Base;
function "+" (Left, Right : Imaginary) return Imaginary;
function "-" (Left, Right : Imaginary) return Imaginary;
function "*" (Left, Right : Imaginary) return Real'Base;
function "/" (Left, Right : Imaginary) return Real'Base;
function "**" (Left : Imaginary; Right : Integer) return Complex;
function "<" (Left, Right : Imaginary) return Boolean;
function "<=" (Left, Right : Imaginary) return Boolean;
function ">" (Left, Right : Imaginary) return Boolean;
function ">=" (Left, Right : Imaginary) return Boolean;
function "+" (Left : Complex; Right : Real'Base) return Complex;
function "+" (Left : Real'Base; Right : Complex) return Complex;
function "-" (Left : Complex; Right : Real'Base) return Complex;
function "-" (Left : Real'Base; Right : Complex) return Complex;
function "*" (Left : Complex; Right : Real'Base) return Complex;
function "*" (Left : Real'Base; Right : Complex) return Complex;
function "/" (Left : Complex; Right : Real'Base) return Complex;
function "/" (Left : Real'Base; Right : Complex) return Complex;
function "+" (Left : Complex; Right : Imaginary) return Complex;
function "+" (Left : Imaginary; Right : Complex) return Complex;
function "-" (Left : Complex; Right : Imaginary) return Complex;
function "-" (Left : Imaginary; Right : Complex) return Complex;
function "*" (Left : Complex; Right : Imaginary) return Complex;
function "*" (Left : Imaginary; Right : Complex) return Complex;
function "/" (Left : Complex; Right : Imaginary) return Complex;
function "/" (Left : Imaginary; Right : Complex) return Complex;
function "+" (Left : Imaginary; Right : Real'Base) return Complex;
function "+" (Left : Real'Base; Right : Imaginary) return Complex;
function "-" (Left : Imaginary; Right : Real'Base) return Complex;
function "-" (Left : Real'Base; Right : Imaginary) return Complex;
function "*" (Left : Imaginary; Right : Real'Base) return Imaginary;
function "*" (Left : Real'Base; Right : Imaginary) return Imaginary;
function "/" (Left : Imaginary; Right : Real'Base) return Imaginary;
function "/" (Left : Real'Base; Right : Imaginary) return Imaginary;
private
type Imaginary is new Real'Base;
i : constant Imaginary := 1.0;
j : constant Imaginary := 1.0;
end Ada.Numerics.Generic_Complex_Types;
Пакет библиотек Numerics.Complex_Types объявлен чистым и определяет те же типы, константы и подпрограммы, что и Numerics.Generic_Complex_Types, за исключением того, что предопределённый тип Float систематически подставляется вместо Real'Base. Аналогично определены непараметризованные аналоги Numerics.Generic_Complex_Types для каждого из других предопределённых типов чисел с плавающей запятой, с именами Numerics.Short_Complex_Types, Numerics.Long_Complex_Types и т. д.
Complex — это видимый тип с декартовыми компонентами.
Imaginary — это приватный тип; его полный тип получен от Real'Base.
Арифметические операции и функции Re, Im, Modulus, Argument и Conjugate имеют свои обычные математические значения. Когда они применяются к параметру чисто мнимого типа, функция «мнимой части» Im возвращает значение его параметра, как соответствующее вещественное значение. Остальные подпрограммы имеют следующие значения:
  • Процедуры Set_Re и Set_Im заменяют указанный компонент комплексного параметра заданным вещественным значением; при применении к параметру чисто мнимого типа процедура Set_Im заменяет значение этого параметра на мнимое значение, соответствующее заданному вещественному значению.
  • Функция Compose_From_Cartesian строит комплексное значение из заданных вещественной и мнимой составляющих. Если задана только одна составляющая, другая составляющая неявно равна нулю.
  • Функция Compose_From_Polar строит комплексное значение из заданного модуля (радиуса) и аргумента (угла). Когда значение параметра Modulus положительно (соответственно, отрицательно), результат является комплексным значением, представленным точкой в комплексной плоскости, находящейся на расстоянии от начала координат, задаваемом абсолютным значением Modulus, и образующей угол, измеряемый против часовой стрелки от положительной (соответственно, отрицательной) действительной оси, задаваемый значением параметра Argument.
Когда параметр Cycle указан, результат функции Argument и параметр Argument функции Compose_From_Polar измеряются в единицах, таких, что полный цикл вращения имеет заданное значение; в противном случае они измеряются в радианах.
Вычисленные результаты математически многозначных функций делаются однозначными с помощью следующих соглашений, которые предполагают главную ветвь:
  • Результат функции Modulus неотрицателен.
  • Результат функции Argument находится в квадранте, содержащем точку в комплексной плоскости, представленную параметром X. Это может быть любой квадрант (I по IV); таким образом, диапазон функции Argument приблизительно от –π до π (–Cycle/2.0 до Cycle/2.0, если указан параметр Cycle). Когда точка, представленная параметром X, лежит на отрицательной действительной оси, результат приближается
  • к π (соответственно, –π), когда знак мнимой составляющей X положителен (соответственно, отрицателен), если Real'Signed_Zeros равен True;
  • к π, если Real'Signed_Zeros равен False.
  • Поскольку результат, лежащий на или вблизи одной из осей, может быть не точно представлен, приближение, присущее вычислению результата, может поместить его в смежный квадрант, близкий, но по неправильную сторону от оси.

Динамическая семантика

Исключение Numerics.Argument_Error генерируется функциями Argument и Compose_From_Polar со специфицированным циклом, сигнализируя о значении параметра вне области соответствующей математической функции, когда значение параметра Cycle равно нулю или отрицательно.
Исключение Constraint_Error генерируется оператором деления, когда значение правого операнда равно нулю, и оператором возведения в степень, когда значение левого операнда равно нулю, а значение показателя степени отрицательно, при условии, что Real'Machine_Overflows равен True; когда Real'Machine_Overflows равен False, результат неопределён. Constraint_Error также может быть сгенерирован, когда конечный результат переполняет (см. G.2.6).

Требования к реализации

При реализации Numerics.Generic_Complex_Types диапазон промежуточных значений, разрешённых во время вычисления конечного результата, не должен быть затронут никакими ограничениями диапазона типа Real.
В следующих случаях вычисление комплексной арифметической операции должно давать предписанный результат, при условии, что предыдущие правила не предусматривают генерирования исключения:
  • Результаты функций Re, Im и Compose_From_Cartesian являются точными.
END_OF_DOCUMENT_MARKER
  • Действительная (соответственно, мнимая) составляющая результата бинарного оператора сложения, дающего результат комплексного типа, является точной, когда любой из его операндов является чисто мнимого (соответственно, действительного) типа.
  • Действительная (соответственно, мнимая) составляющая результата бинарного оператора вычитания, дающего результат комплексного типа, является точной, когда его правый операнд является чисто мнимого (соответственно, действительного) типа.
  • Действительная составляющая результата функции Conjugate для комплексного типа является точной.
  • Когда точка в комплексной плоскости, представленная параметром X, лежит на неотрицательной действительной оси, функция Argument возвращает результат нуль.
  • Когда значение параметра Modulus равно нулю, функция Compose_From_Polar возвращает результат нуль.
  • Когда значение параметра Argument равно кратному четверти цикла, результат функции Compose_From_Polar со специфицированным циклом лежит на одной из осей. В этом случае одна из его составляющих равна нулю, а другая имеет величину параметра Modulus.
  • Возведение в степень с нулевым показателем дает значение один. Возведение в степень с единичным показателем дает значение левого операнда. Возведение в степень значения один дает значение один. Возведение в степень значения ноль дает значение ноль, при условии, что показатель отличен от нуля. Когда левый операнд является чисто мнимого типа, одна составляющая результата оператора возведения в степень равна нулю.
Когда результат или составляющая результата любого оператора из Numerics.Generic_Complex_Types имеет математическое определение в терминах одной арифметической или реляционной операции, этот результат или составляющая результата демонстрирует точность соответствующей операции типа Real.
Другие требования к точности функций Modulus, Argument и Compose_From_Polar, а также требования к точности умножения пары комплексных операндов или деления на комплексный операнд, которые применяются только в строгом режиме, приведены в G.2.6.
Знак нулевого результата или нулевой составляющей результата, полученного в результате комплексной арифметической операции или функции, определяется реализацией, когда Real'Signed_Zeros имеет значение True.

Разрешения на реализацию

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

Рекомендации по реализации

Поскольку обычный математический смысл умножения комплексного операнда и действительного операнда заключается в масштабировании обеих составляющих первого операнда на второй, реализация не должна выполнять эту операцию путем предварительного преобразования действительного операнда к комплексному типу и последующего выполнения полного комплексного умножения. В системах, которые в будущем будут поддерживать Ada-связь с IEC 559:1989, последний метод не будет генерировать требуемый результат, когда одна из составляющих комплексного операнда является бесконечной. (Явное умножение бесконечной составляющей на нулевую составляющую, полученную во время преобразования, приводит к NaN, который распространяется на конечный результат.) Аналогичные рекомендации применяются в случае умножения комплексного операнда и чисто мнимого операнда и в случае деления комплексного операнда на действительный или чисто мнимый операнд.
Аналогично, поскольку обычный математический смысл сложения комплексного операнда и действительного операнда состоит в том, что мнимая составляющая остается неизменной, реализация не должна выполнять эту операцию, предварительно преобразуя действительный операнд в комплексный тип и затем выполняя полное комплексное сложение. В реализациях, в которых атрибут Signed_Zeros типа составляющей имеет значение True (и которые, следовательно, соответствуют IEC 559:1989 в отношении обработки знака нуля в предопределенных арифметических операциях), последний метод не будет генерировать требуемый результат, когда мнимая составляющая комплексного операнда является отрицательно-знаковым нулем. (Явное сложение отрицательного нуля с нулем, полученным во время преобразования, даёт положительный ноль.) Аналогичные рекомендации применяются в случае сложения комплексного операнда и чисто мнимого операнда и в случае вычитания комплексного операнда и действительного или чисто мнимого операнда.
Реализации, в которых Real'Signed_Zeros имеет значение True, должны стремиться обеспечить рациональную обработку знаков нулевых результатов и нулевых составляющих результатов. Например, результат функции Argument должен иметь знак мнимой составляющей параметра X, когда точка, представленная этим параметром, лежит на положительной действительной оси; в качестве другого примера, знак мнимой составляющей функции Compose_From_Polar должен быть таким же (соответственно, противоположным), как у параметра Argument, когда этот параметр имеет значение ноль, а параметр Modulus имеет неотрицательное (соответственно, отрицательное) значение.


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API