-1

Ada の使用 (GNAT): 特定の値の 10 のべき乗を決定する必要があります。最も明白なアプローチは、対数を使用することです。しかし、それはコンパイルに失敗します。

with Ada.Numerics.Generic_Elementary_Functions;
procedure F(Value : in Float) is
      The_Log : Integer := 0;
begin
      The_Log := Integer(Log(Value, 10));
      G(Value, The_Log);
end;

エラー:

  • utility.adb:495:26: 「ログ」が表示されない
    • utility.adb:495:26: a-ngelfu.ads:24 の非表示宣言、482 行のインスタンス
    • utility.adb:495:26: a-ngelfu.ads:23 の非表示宣言、482 行目のインスタンス

そのため、パッケージを参照しようとしましたが、それも失敗しました:

with Ada.Numerics.Generic_Elementary_Functions;
procedure F(Value : in Float) is
      The_Log : Integer := 0;
      package Float_Functions is new Ada.Numerics.Generic_Elementary_Functions (Float);
begin
      The_Log := Integer(Float_Functions.Log(Value, 10));
      G(Value, The_Log);
end;

エラー:

  • utility.adb:495:41: 候補の解釈が実際のものと一致しません:
  • utility.adb:495:41: "Log" の呼び出しで引数が多すぎます
  • utility.adb:495:53: 期待される型 "Standard.Float"
  • utility.adb:495:53: a-ngelfu.ads:24 の「Log」の呼び出しで型の汎用整数 ==> が見つかりました、482 行目のインスタンス
4

2 に答える 2

6

すでに修正されているかどうかはわかりませんが、ここに答えがあります。

まず第一にFloat、ジェネリック バージョンをインスタンス化するときにパスしているように、代わりに非ジェネリック バージョンを使用できます。

汎用バージョンを使用する場合は、2 番目の方法で行う必要があります。その関数を使用する前に、パッケージをインスタンス化する必要があります。

a-ngelfu.adsを見ると、必要な関数の実際のプロトタイプが表示される場合があります (パラメータが 1 つだけの自然対数用の別の関数があります)。

function Log(X, Base : Float_Type'Base) return Float_Type'Base;

base も float 型にする必要があることがわかります。ジェネリック バージョンの正しいコードは次のようになります。

with Ada.Numerics.Generic_Elementary_Functions;

procedure F(Value : in Float) is
    -- Instantiate the package:
    package Float_Functions is new Ada.Numerics.Generic_Elementary_Functions (Float);
    -- The logarithm:
    The_Log : Integer := 0;
begin
    The_Log := Integer(Float_Functions.Log(Value, 10.0));
    G(Value, The_Log);
end;

非一般的なものはまったく同じです:

with Ada.Numerics.Elementary_Functions;

procedure F(Value : in Float) is
    -- The logarithm:
    The_Log : Integer := 0;
begin
    The_Log := Integer(Ada.Numerics.Elementary_Functions.Log(Value, 10.0));
    G(Value, The_Log);
end;
于 2010-02-10T11:47:41.533 に答える
3

ザンディは正しいです。彼の解決策はうまくいきました。

ただし、Ada には 2 つの例外があります。

  • 値 < 0.0
  • 値 = 0.0

ガードなしでこの関数をそのまま使用すると、例外が生成されます。また、返される The_Log が < 0、0、および > 0 になる可能性があることを覚えておいてください。

with Ada.Numerics.Elementary_Functions; 

procedure F(Value : in Float) is 
    -- The logarithm: 
    The_Log : Integer := 0; 
begin 
    if Value /= 0.0 then
        The_Log := Integer(
             Ada.Numerics.Elementary_Functions.Log(abs Value, 10.0)); 
    end if;
    G(Value, The_Log); 
end; 
于 2010-02-11T05:03:17.127 に答える