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
Foi útil?

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; 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top