1

(小さな) 分子と分母を、ほとんどの小さな数で割り切れ、2**63 のすぐ下になるように選択された、大きな定数分母の観点から分子に変換しようとしています。オーバーフローする可能性があるため、プラグマ Overflow_Mode (Eliminated) を使用します (GNAT 4.8 マニュアルhttp://gcc.gnu.org/onlinedocs/gcc-4.8.0/gnat_ugn_unw/Specifying-the-Desired-Mode. html#目的のモードの指定)。

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 が丸められることを受け入れるだけですが、これを機能させたいと思います。適切な無限長ここでは整数のサポートはやり過ぎです。)

4

1 に答える 1

1

完全な答えではありませんが、Large_Composite を保持するのに十分な大きさの Long_Long_Integer を使用すると、Integer の代わりに警告が抑制され、pragma Overflow_Mode が機能し、N = 99 や D = 100 などを使用して正しい答えを得ることができます。この計算モデルにはまだ一貫性がないように見えますが、少なくともコードは機能しています。

于 2013-06-11T08:22:17.517 に答える