我试图用一个大的常数分母将(小)分子和分母转换成分子,选择它可以被大多数小数整除,并且刚好低于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
Hrumph。我不明白Overflow_Mode是做什么的吗?是否有一些简单的方法来重新安排它,所以它的工作原理? (我可以去计划A,一个更正常的分数类,可能会或可能不会更快或计划B,只使用浮点数并接受1/3将得到四舍五入,但我希望这可以工作。适当的无限长度整数支持在这里是过度的。)
答案 0 :(得分:1)
这不是一个完整的答案,但是使用Long_Long_Integer,它足够容纳Large_Composite而不是Integer会抑制警告,并且编译指示Overflow_Mode完成它的工作并让我使用N = 99和D = 100这样的东西并得到正确答案。这个计算模型似乎仍然有点不一致,但至少代码是有效的。