Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11

Discussione: [delphi] RoundTo

  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2002
    Messaggi
    1,326

    [delphi] RoundTo

    Ciao a tutti,

    ho un problema di arrotondamento...ho cercato in rete e non ho capito come fare per risolvere.

    devo arrotondre un numero a 2 cifre decimali. capita che la stessa cifra decimale viene arrotondata al suo inferiore in un caso e al suo superiore in un secondo caso.

    127.1650--> RoundTo(127.1650,-2) = 127,17
    766.1650--> RoundTo(766.1650,-2) = 766,16

    avete suggerimenti su come posso risolvere?

    grazie

  2. #2
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Se vuoi fare una funzione "euroarrotonda" ti segnalo che è molto, ma molto, ma davvero mooooooooooooooolto più difficile di quello che può sembrare (nell'ipotesi di volerne fare una davvero affidabile in ogni situazione)

  3. #3
    Tip "giusto per stare sicuri", sempre nel caso in cui tu stia lavorando con importi monetari: se possibile usa il tipo Decimal, ti risparmierai diversi mal di testa.
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Originariamente inviato da MItaly
    Tip "giusto per stare sicuri", sempre nel caso in cui tu stia lavorando con importi monetari: se possibile usa il tipo Decimal, ti risparmierai diversi mal di testa.
    In Delphi non esiste.

  5. #5
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Comunque se l'effetto voluto è un euro-arrotondatore questo è quanto uso, con tanto di tristissime patch per (s)vista e certi problemini di stabilità numerica in prossimità dello zero, soprattutto per processori AMD, con tanto di "riprova" (!!!!!!)

    codice:
    function	EuroArrotonda(x:double):double;
    var
       myx:double;
       euro2:double;
    
    function	EuroArrotonda2(x:double):double;
    var
       testostringa:string;
       posizionepunto:integer;
       ultimacifra:integer;
       parteintera:string;
       i:integer;
       parteinterainteger:integer;
    begin
       result:=x;
    
       testostringa:=floattostr(x*100.0);
       testostringa:=stringreplace(testostringa,'.',',',[rfreplaceall]);
       posizionepunto:=pos(',',testostringa);
       if posizionepunto>0 then
           if posizionepunto<length(testostringa) then
           begin
               ultimacifra:=strtoint(testostringa[posizionepunto+1]);
               parteintera:='';
               for i:=1 to posizionepunto-1 do
                   parteintera:=parteintera+testostringa[i];
               if ultimacifra>=5 then
                   parteinterainteger:=strtoint(parteintera)+1
               else
                   parteinterainteger:=strtoint(parteintera);
               result:=parteinterainteger / 100.0;
            end;
    end;
    begin
       // fix strano per vista. mah....
       if x<10E-9 then
       begin
        //   myshowmessage('Arrotondo a zero '+floattostr(x));
           x:=0;
       end;
       if x>10E15 then
       begin
           //myshowmessage('Valore eccessivo => arrotondo a zero '+floattostr(x));
           x:=0;
       end;
    
       myX:=x;
    
       try
           x:=x*100.0;
    
       //vecchio x := Trunc(X) + Trunc (Frac(X) * 2);
    
           if abs(Frac(x)-0.5)<0.0000001 then
               x := Trunc(X) + 1
           else
               x := Trunc(X) + Trunc (Frac(X) +Frac(X));
    
           x:=x/100.0;
       except
           //frmgurumeditation.i_messaggio:='Euroarrotonda 19539 '+floattostr(myX);
       end;
    
       result:=x;
       if myX>=0.000001 then
       // accidenti è una situazione numericamente instabile, verifica
       begin
           euro2:=euroarrotonda2(myx);
           if floattostr(x)<>floattostr(euro2) then
           begin
               //frmgurumeditation.i_messaggio:='Euroarrotonda: '+floattostr(myx)+' a1= '+floattostr(x)+' <> a2='+floattostr(euro2);
           end;
       end;
    end;

  6. #6
    Ma è inguardabile... non c'è modo di usare un tipo decimal/currency/... ed evitare tutto 'sto pasticcio? Poi la storia del fix per Vista mi suona stranissima, l'unica spiegazione che vedo è che in qualche maniera qualche dll caricata su Vista (o il runtime Delphi su Vista) cambino qualche impostazione della FPU...
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2002
    Messaggi
    1,326
    ciao ragazzi,

    il problema si riferisce ad importi di una fattura in euro.

    in delphi esiste tipo currency che ha 4 decimali, ed il problema nasce nell'approssimazione di questi decimali.

    sto sbattendo la testa cercando una buona soluzione...

    e comunque non capisco perchè la stessa parte decimale la arrotonda diversamente..


    127.1650--> RoundTo(127.1650,-2) = 127,17
    766.1650--> RoundTo(766.1650,-2) = 766,16


  8. #8
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Euroarrotonda e passa la paura

  9. #9
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Originariamente inviato da MItaly
    Ma è inguardabile...
    Però funziona
    non c'è modo di usare un tipo decimal/currency/... ed evitare tutto 'sto pasticcio?
    no
    Poi la storia del fix per Vista mi suona stranissima, l'unica spiegazione che vedo è che in qualche maniera qualche dll caricata su Vista (o il runtime Delphi su Vista) cambino qualche impostazione della FPU...
    certo che suona strano, suonava strano fino a me finquando non ho dovuto fare la patch.

  10. #10
    Originariamente inviato da franzauker2.0
    Però funziona
    Non ne dubito, solo che passare per delle stringhe per fare un arrotondamento suona un attimo bizzarro.
    no
    Se lavori direttamente in Currency/Decimal/come lo vuoi chiamare non dovresti avere problemi di arrotondamento dovuti agli errori FP, dato che aggiri in blocco il problema dei numeri in virgola mobile e tutti i casini che ne derivano...
    certo che suona strano, suonava strano fino a me finquando non ho dovuto fare la patch.
    Consiglio: a me ad un certo punto era capitata una roba del genere (in C, però), in cui codice esterno (=dll di terze parti caricate nel processo per vie traverse, tipo shell extension caricate dal filedialog) incasinava la control word della FPU lasciandola in uno stato bizzarro (arrotondava in maniere strane o sollevava eccezioni FPU, ora di preciso non ricordo); per caso mi ero imbattuto in questa roba che a sua volta rimanda a questo e questo, vedi se ti può essere utile (io avevo risolto appunto con l'analoga chiamata in C).
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.