Как вы код для определения логарифма значения в Аде? - PullRequest
0 голосов
/ 10 февраля 2010

Использование Ada (GNAT): мне нужно определить степень десяти для данного значения. Наиболее очевидный подход - использовать логарифм; но это не удается скомпилировать.

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;

ошибка:

  • utilities.adb: 495: 26: «Журнал» не отображается
    • utilities.adb: 495: 26: невидимое объявление в a-ngelfu.ads:24, экземпляр в строке 482
    • utilities.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;

ошибка:

  • utilities.adb: 495: 41: ни одно из возможных толкований не соответствует действительности:
  • utilities.adb: 495: 41: слишком много аргументов при вызове «Log»
  • utilities.adb: 495: 53: ожидаемый тип «Standard.Float»
  • utilities.adb: 495: 53: найдено универсальное целое число типа ==> при вызове «Log» в a-ngelfu.ads:24, экземпляр в строке 482

Ответы [ 2 ]

5 голосов
/ 10 февраля 2010

Я не знаю, исправили ли вы это уже или нет, но вот ответ.

Прежде всего, как я вижу, вы передаете Float при создании экземпляра универсальной версии, вместо этого вы можете использовать не универсальную.

Если вы решите использовать универсальную версию, вам нужно будет сделать это вторым способом, прежде чем использовать его функции, необходимо создать экземпляр пакета.

Глядя на a-ngelfu.ads , вы можете увидеть фактический прототип нужной вам функции (есть еще одна функция для натурального логарифма с одним параметром):

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

Вы можете видеть там, что база тоже должна быть типа с плавающей точкой. Правильный код для универсальной версии будет:

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;
3 голосов
/ 11 февраля 2010

Xandy прав. Его решение сработало.

Однако, будучи Ада, было два исключения для защиты от ...

  • Значение <0.0 </li>
  • Значение = 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; 
...