Newsgroup: it.comp.lang.delphi
Titolo: Strani arrotondamenti

Salve a tutti.
Ho notato una stranezza utilizzando la proprieta' DisplayFormat
di alcuni oggetti. In pratica, volendo arrotondare a 2 cifre decimali
un valore di un campo di un DB (chissa perche', eh ?), ho impostato
appunto la DisplayFormat con la stringa #.00 e qui la stranezza:
il valore 7.845 me lo arrotonda a 7.84 e il valore 8.845 me lo
arrotonda a 8.85.
A questo punto ho provato un piccolo esperimento e ho fatto
girare la seguente procedura:
procedure TForm1.Button1Click(Sender: TObject);
var ValDec: Real;
    ErrCod: Integer;
    S     : String;
begin
  S:= EdIn.Text;
  val(S,ValDec,ErrCod);
  EdOut.Text:= Format('%.2f',[ValDec])
end;
Stessi valori, stessssssssi risultati.
Ora, lasciando perdere il fatto che lo stesso programmino
in VB funziona, (come anche l'arrotondamento in Excel)
mentre invece una printf ".2f%" XXX in ambiente unix
mi da gli stessi errori, che succede ?
In quale problema (probabilmente noto al mondo intero
tranne che al sottoscritto) sono incappato ?
E, soprattutto, posso uscirne senza dover riscrivere
delle routine di arrotondamento apposite ?

 delle routine di arrotondamento apposite ?
Prima soluzione che mi viene in mente è quella di usare un campo double, la
cui precisione dovrebbe essere talmente alta da eliminare problemi di questo
tipo (tranne per i casi ultra-limite).
Spero di esserti stato utile.
ciao
--------------------------------------------
Per rispondere in privato rimuovere "1975"
Assistenza Samsung: Dopo 4 mesi ancora il nulla (Anzi mi hanno rotto la
telecamera)
--------------------------------------------

tipo (tranne per i casi ultra-limite).
Ho provato ad usare un campo double ma mi da ancora
gli stessi errori (ARGH !!!)
Per la precisione l'arrotondamento funziona solo con numeri
la cui parte intera va da 8 a 15 compresi... no l'e' posibile.
AIUto...


ABLS Team - 
www.abls.it
SINTESI S.r.l. - 
www.sintesi.com


Ma l'arrotondamento classico <=x.4->x;>=x.5->x+1 bisogna farlo a mano o
esiste una unit in grado di comportarsi come il resto del mondo (il banker's
rounding e' tipicamente americano)?
Ciaotutti,
*


Come ho scritto nel messaggio, la unit Math.pas di Delphi 6 include funzioni
per l'arrotondamento come intendi tu; per le versioni precedenti, ho paura
che dovrai creare un metodo ad hoc.
Anzi, sarebbe interessante se qualcuno ha qualche idea su come implementarlo
ho ha già trovato soluzioni alternative efficienti.
Ciao!!


ho provato ad inserire un campo calcolato e se uso un "real" funziona, pero'
ho visto che in delphi6 (non ho il 5) devi usare il "real48"
il real mi viene dichiarato come
Real
Min: 2.9 * 10e-39 ..
Max: 1.7 * 10e38
Cifre significative: 11-12
Dimensione 6
la funziona di calcolo è del tipo
procedure TForm1.Table1CalcFields(DataSet: TDataSet);
var d : real; // è possibile che in d5 il real sia stato cambiato (con il 6
sono sicuro)
begin
 d := Table1Vvvv.value;
 Table1valore.value := (round(d*100))/100;
end;
Table1Vvvv.value è il campo di valute
Table1valore.value è il campo calcolato.
ciao
--------------------------------------------
Per rispondere in privato rimuovere "1975"
Dopo quasi 5 mesi ancora il nulla (Anzi mi hanno rotto la telecamera)
--------------------------------------------


Da quanto avevi scritto sembrava una funzione tipo Ceil() (non mi chiedete
di quale linguaggio perche' non me lo ricordo assolutamente), che arrotonda
SEMPRE per eccesso...
Ciaotutti,
*

 SEMPRE per eccesso...
Il linguaggio e' il C e le funzioni sono ceil() e floor().
La prima arrotonda per eccesso, la seconda per difetto.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

Ciao!!
Vabbuo'.
Grazie a tutti e la mezza decisione e' diventata intera:
passo al 6.
Ciao.

passo al 6.
Allora. Detto e fatto.
Installata la versione trial (tra parentesi, D6 spettacolo),
utilizzata la nuova RoundTo, risultato ?
Tale e quale a prima.
Tra l'altro l'help della funzione presenta degli esempi di
arrotondamento con l'errore.
A questo punto sono gia' sullo sgabello con la corda
in mano: qualcuno mi dia un motivo per fermarmi.

 in mano: qualcuno mi dia un motivo per fermarmi.
procedure TForm1.edtImportoEuroExit(Sender: TObject);
var
  Euro: Double;
begin
  Euro := StrToFloat(edtImportoEuro.Text);
  Euro := Int(Euro * 100 + 0.5) / 100;
  edtImportoEuro.Text := FloatToStr(Euro);
end;


end;
Avevo gia' provato (e ho riprovato per scrupolo) ma
si conferma l'errore.
SOB !

 si conferma l'errore.
Strano.
L'arrotondamento come ti ho suggerito fa esattamente
cio' di cui hai bisogno e sulla mia macchina funziona
perfettamente.


usa questa
function Round(x: double): double;
begin
  result:=Trunc(x)+Trunc(Frac(x)*2);
end;
Paolo


perfettamente.
Non so che dirti, non so veramente piu' che pesci pigliare.

end;
Ma cosi' mi arrotonda all'intero superiore.
A me servono i primi due decimali.

> Non so che dirti, non so veramente piu' che pesci pigliare.
prova questa
function ArrotondaPrezzo(Value: Currency;
  NoDecimali: Word): Currency;
var
  Moltiplicatore: Integer;{è un numero esponenziale di 10: 1, 10, 100, 1.000,
10.000}
  i: Word;
  F: Extended;
begin
  Moltiplicatore := 1;
  for i := 1 to NoDecimali do Moltiplicatore := Moltiplicatore * 10;
  Value := Value * Moltiplicatore;         
  F := Frac(Value);
  if (F <> 0) and (F >= 0.5) then
    Value := Int(Value) + 1
  else
    Value := Int(Value);
  Result := Value / Moltiplicatore;  
end;
