Domanda

Utilizzando Ada (GNAT): Ho bisogno di determinare la potenza di dieci per un dato valore. L'approccio più ovvio è quello di utilizzare un logaritmo; ma che non riesce a compilare.

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;

errore:

  • utilities.adb: 495: 26: "Log" non è visibile
    • utilities.adb: 495: 26: dichiarazione non visibile a-ngelfu.ads:24, esempio alla riga 482
    • utilities.adb: 495: 26: dichiarazione non visibile a-ngelfu.ads:23, esempio alla riga 482

Allora tento di fare riferimento al pacchetto, ma che fallisce anche:

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;

errore:

  • utilities.adb: 495: 41: nessun interpretazioni candidati corrispondono ai valori effettivi:
  • utilities.adb: 495: 41: troppi argomenti nella chiamata a "Log"
  • utilities.adb: 495: 53: tipo previsto "Standard.Float"
  • utilities.adb: 495: 53: trovato tipo intero universale ==> in chiamata a "Log" a a-ngelfu.ads:24, esempio alla linea 482
È stato utile?

Soluzione

Non so se è stato risolto già o no, ma qui è la risposta.

Prima di tutto, per come la vedo si sta passando Float quando si crea un'istanza della versione generica che si può usare quello non generica, invece.

Se si decide di utilizzare la versione generica che dovete fare è il secondo modo che hai fatto, è necessario istanziare il pacchetto prima di utilizzare le sue funzioni.

Guardando a-ngelfu.ads è possibile vedere il prototipo reale della funzione desiderata (c'è un'altra funzione per il logaritmo naturale con appena 1 parametro):

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

Si può vedere lì che la base ha bisogno di essere in un tipo float troppo. Il codice corretto per la versione generica potrebbe essere:

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;

L'uno non generico sarebbe esattamente lo stesso:

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;

Altri suggerimenti

Xandy è giusto. La sua soluzione ha funzionato.

Tuttavia essendo Ada c'erano due eccezioni per tutelarsi dai ...

  • Valore <0.0
  • Value = 0.0

Senza guardie questa funzione in quanto è causa eccezioni da generare. E ricordate The_Log come restituito può essere <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; 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top