Como você código para determinar o logaritmo de um valor em Ada?
Pergunta
Usando Ada (GNAT): Eu preciso para determinar a potência de dez para um dado valor. A abordagem mais óbvia é usar um logaritmo; mas que não consegue compilar.
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;
Erro:
- utilities.adb: 495: 26: "Log" não é visível
- utilities.adb: 495: 26: declaração de não-visível a a-ngelfu.ads:24, instância na linha 482
- utilities.adb: 495: 26: declaração de não-visível a a-ngelfu.ads:23, instância na linha 482
Então eu tentar se referir ao pacote, mas isso também falhar:
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;
Erro:
- utilities.adb: 495: 41: há interpretações candidatos corresponder aos valores reais:
- utilities.adb: 495: 41: muitos argumentos em call "Log"
- utilities.adb: 495: 53: esperava tipo "Standard.Float"
- utilities.adb: 495: 53: encontrados tipo inteiro universal ==> na chamada para "Log" no a-ngelfu.ads:24, instância na linha 482
Solução
Eu não sei se você fixa-lo já ou não, mas aqui está a resposta.
Antes de mais nada, como eu ver que você está passando Float
ao instanciar a versão genérica você pode usar o não genérico em vez.
Se você decidir usar a versão genérica você tem que fazê-lo da segunda maneira que você fez, você tem que instanciar o pacote antes de utilizar suas funções.
Olhando para a-ngelfu.ads você pode ver o protótipo real da função que você precisa (há uma outra função para o logaritmo natural com apenas 1 parâmetro):
function Log(X, Base : Float_Type'Base) return Float_Type'Base;
Você pode ver lá que a base precisa estar em um tipo float também. O código correto para a versão genérica seria:
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;
O único não-genérico seria exatamente o mesmo:
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;
Outras dicas
Xandy é certo. Sua solução funcionou.
No entanto a ser Ada houve duas exceções para proteger contra ...
- Valor <0,0
- Valor = 0,0
Sem guardas esta função, pois é causa exceções a serem gerados. E lembre-se The_Log como retornado pode ser <0, 0 e> 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;