Справочник Ada 2005
G.2.3 Модель фиксированной арифметики
В строгом режиме предопределённые арифметические операции типа с фиксированной точкой должны удовлетворять требованиям точности, указанным здесь, и должны избегать переполнения или сигнализировать о нём в описанных ситуациях.
Требования к реализации
Ниже приведены требования к точности предопределённых операций с фиксированной точкой и преобразований, а также результатов отношений над операндами с фиксированной точкой.
Операторы сложения с фиксированной точкой, абсолютное значение и сравнения имеют операнды одного типа. Эти операции должны давать точные результаты, если они не вызывают переполнение.
Умножения и деления разрешены между операндами любых двух типов с фиксированной точкой; результат должен быть (явным или неявным) преобразован в какой-либо другой числовой тип. Для целей определения правил точности умножение или деление и преобразование рассматриваются как одна операция, точность которой зависит от трёх типов (операндов и результата). Для типов десятичной фиксированной точки можно использовать атрибут T'Round, чтобы подразумевать явное преобразование с округлением (см. 3.5.10).
Когда тип результата — тип с плавающей точкой, точность задаётся в G.2.1. Для некоторых сочетаний типов операндов и результата в остальных случаях результат должен принадлежать малому набору значений, называемому идеальным набором результатов; для других сочетаний требуется лишь принадлежность к более широкому, определённому реализацией набору значений, называемому близким набором результатов. Когда тип результата — десятичный тип с фиксированной точкой, идеальный набор результатов содержит единственное значение; таким образом, операции над десятичными типами всегда полностью определены.
Когда один из операндов умножения или деления фиксированной точки имеет тип universal_real, этот операнд не преобразуется неявным образом в обычном смысле, так как контекст не определяет уникальный целевой тип, но точность результата умножения или деления (т. е. должен ли результат принадлежать идеальному набору результатов или только близкому набору результатов) зависит от значения операнда типа universal_real и от типов другого операнда и результата.
Для умножения или деления с фиксированной точкой, точный математический результат которого v, и для преобразования значения v в тип с фиксированной точкой, идеальный набор результатов и близкий набор результатов определяются следующим образом:
- Если тип результата — обычный тип с фиксированной точкой с small s,
- если v является целым кратным s, то идеальный набор результатов содержит только значение v;
- в противном случае он содержит целое кратное s чуть меньше v и целое кратное s чуть больше v.
- Близкий набор результатов — это определяемый реализацией набор последовательных целых кратных s, содержащий идеальный набор результатов как подмножество.
- Если тип результата — десятичный тип с small s,
- если v является целым кратным s, то идеальный набор результатов содержит только значение v;
- в противном случае, если применяется усечение, то он содержит только целое кратное s в направлении к нулю, а если применяется округление, то он содержит только ближайшее целое кратное s (в случае равенства ближайших кратных — округление от нуля).
- Близкий набор результатов — это определяемый реализацией набор последовательных целых кратных s, содержащий идеальный набор результатов как подмножество.
- Если тип результата — целочисленный тип,
- если v — целое число, то идеальный набор результатов содержит только значение v;
- в противном случае он содержит ближайшее к значению v целое число (если v равноудалено от двух последовательных целых чисел, то идеальный набор результатов содержит то, которое дальше от нуля).
- Близкий набор результатов — это определяемый реализацией набор последовательных целых чисел, содержащий идеальный набор результатов как подмножество.
Результат умножения или деления с фиксированной точкой должен принадлежать либо идеальному, либо близкому набору результатов, как описано ниже, если не происходит переполнение. В следующих случаях, если тип результата — тип с фиксированной точкой, пусть s будет его small; в противном случае, т. е. когда тип результата — целочисленный тип, пусть s будет 1.0.
- Для умножения или деления, ни один из операндов которого не имеет типа universal_real, пусть l и r будут small левого и правого операндов. При умножении, если (l · r) / s — целое число или обратная величина целого числа (small в этом случае считаются «совместимыми»), результат должен принадлежать идеальному набору результатов; в противном случае он принадлежит близкому набору результатов. При делении, если l / (r · s) — целое число или обратная величина целого числа (т. е. small совместимы), результат должен принадлежать идеальному набору результатов; в противном случае он принадлежит близкому набору результатов.
- Для умножения или деления с одним операндом universal_real со значением v, обратите внимание, что всегда возможно разложить v в виде целого кратного «совместимого» small, но целое кратное может быть «слишком большим». Если существует разложение, в котором это кратное меньше некоторого определяемого реализацией предела, результат должен принадлежать идеальному набору результатов; в противном случае он принадлежит близкому набору результатов.
Умножение P * Q операнда типа с фиксированной точкой F на операнд целочисленного типа I, или наоборот, и деление P / Q операнда типа с фиксированной точкой F на операнд целочисленного типа I также разрешены. В этих случаях результат имеет тип F; явное преобразование результата никогда не требуется. Требуемая точность в этих случаях такая же, как для умножения F(P * Q) или деления F(P / Q), полученных путём интерпретации операнда целочисленного типа как имеющего тип с фиксированной точкой со small 1.0, согласно вышеизложенным правилам.
Точность результата преобразования из целочисленного или типа с фиксированной точкой в тип с фиксированной точкой или из типа с фиксированной точкой в целочисленный тип такая же, как и при умножении значения источника на операнд с фиксированной точкой, имеющий small 1.0 и значение 1.0, согласно вышеприведённым правилам. Результат преобразования из типа с плавающей точкой в тип с фиксированной точкой должен принадлежать близкому набору результатов. Результат преобразования операнда universal_real в тип с фиксированной точкой должен принадлежать идеальному набору результатов.
Возможные переполнения в результате предопределённой арифметической операции или преобразования, дающего результат типа с фиксированной точкой T, аналогичны таковым для типов с плавающей точкой, за исключением того, что они связаны с базовым диапазоном, а не с безопасным диапазоном. Если все допустимые результаты принадлежат базовому диапазону T, то реализация должна вернуть один из допустимых результатов; в противном случае,
- если T'Machine_Overflows — True, реализация должна либо вернуть один из допустимых результатов, либо вызвать Constraint_Error;
- если T'Machine_Overflows — False, результат определяется реализацией.