我正在尝试将(小)分子和分母转换为大常数分母的分子,选择为可被大多数小数整除并且略低于 2**63。由于这可能会溢出,我将使用 pragma Overflow_Mode(已消除)(参见 GNAT 4.8 手册http://gcc.gnu.org/onlinedocs/gcc-4.8.0/gnat_ugn_unw/Specifying-the-Desired-Mode。 html#Specifying-the-Desired-Mode)。
with Ada.Command_Line;
with Ada.Text_IO;
procedure Example is
pragma Overflow_Mode (Eliminated);
Large_Composite : constant := (2 ** 7) * (3 ** 5) * (5 ** 2) * 7
* 11 * 13 * 17 * 19 * 23 * 29 * 31 * 37 * 41;
type Word_Unsigned is mod 2**64;
N, D : Integer;
begin
N := Integer'Value (Ada.Command_Line.Argument (1));
D := Integer'Value (Ada.Command_Line.Argument (2));
Ada.Text_IO.Put (Word_Unsigned ((N * Large_Composite) / D)'Img);
end Example;
不幸的是,当尝试使用“~/bin/gcc-4.8.0/bin/gnatmake -gnat12 -gnata -Wall example.adb”(和 -gnato3,尽管这对于编译指示来说应该是多余的),但编译器说:
example.adb:12:46: value not in range of type "Standard.Integer"
example.adb:12:46: static expression fails Constraint_Check
gnatmake: "example.adb" compilation error
哼哼。我不明白 Overflow_Mode 是做什么的吗?有没有一些简单的方法可以重新排列它以使其有效?(我可以去计划 A,一个更正常的分数类,可能更快也可能不会更快,或者计划 B,只使用浮点数并接受 1/3 将被四舍五入,但我希望这个工作。适当的无限长度整数支持在这里是多余的。)