Как вы программируете для определения логарифма значения в Ada?
Вопрос
Использование 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;
ошибка:
- коммунальные услуги.adb:495:26:"Журнал регистрации" не виден
- коммунальные услуги.adb:495:26:невидимое объявление в a-ngelfu.ads:24, например, в строке 482
- коммунальные услуги.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;
ошибка:
- коммунальные услуги.adb:495:41:ни одна из возможных интерпретаций не соответствует действительности:
- коммунальные услуги.adb:495:41:слишком много аргументов в вызове "Log"
- коммунальные услуги.adb:495:53:ожидаемый тип "Стандартный.Плавающий"
- коммунальные услуги.adb:495:53:найдено тип universal integer ==> в вызове "Log" в a-ngelfu.ads:24, экземпляр в строке 482
Решение
Я не знаю, исправили вы это уже или нет, но вот ответ.
Во-первых, как я вижу, вы проходите мимо Float
при создании экземпляра универсальной версии вы можете использовать вместо нее не универсальную версию.
Если вы решите использовать универсальную версию, вам придется сделать это вторым способом, который вы сделали, вы должны создать экземпляр пакета, прежде чем использовать его функции.
Глядя на a-ngelfu.объявления вы можете увидеть фактический прототип нужной вам функции (есть еще одна функция для натурального логарифма всего с 1 параметром).:
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;
Другие советы
Ксэнди права.Его решение сработало.
Однако, будучи Адой, нужно было остерегаться двух исключений...
- Значение < 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;