Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Arrotondamento su cifre che rappresentano Euro (prezzi)

31 views
Skip to first unread message

capsula

unread,
Dec 15, 2011, 10:19:40 AM12/15/11
to
Vorrei che in uno script CGI il valore della variabile $costo sia
troncata con le regole dell'Euro essendo un prezzo.
Mi serve troncare esatto altrimenti si creano incoerenze nei calcoli
successivi.

$costo = $rendita_60*100;

Le regole del troncamento alla seconda cifra decimale sono codificate come:

Se la terza cifra decimale è minore di 5 , si arrotonda per difetto ;

Se è maggiore o uguale a 5 , si arrotonda per eccesso.

Esempio :

cifra = 51,645(689) > valore in euro 51,65 (arrotondato per eccesso)

cifra = 25,822(844) > valore in euro 25,82(arrotondato per difetto)

Non trovo nulla nelle opzioni dei comandi sprintf dove ho cercato.

Grazie

Andrea Maestrutti

unread,
Dec 15, 2011, 10:28:36 AM12/15/11
to
capsula wrote:
> Vorrei che in uno script CGI il valore della variabile $costo sia
> troncata con le regole dell'Euro essendo un prezzo.

Visto il problema, sottolineato in

<http://www.perl.it//documenti/faq/view.html?pag=4&faq=4>

va usato CPAN, tipo:

<http://search.cpan.org/~grommel/Math-Round-0.06/Round.pm>

capsula

unread,
Dec 15, 2011, 12:18:49 PM12/15/11
to
ti ringrazio di cuore per la risposta così rapida.

purtroppo non credo di poter compilare o aggiungere moduli al perl sul
server.

il cgi va eseguito sui server tophost partendo da una pagina web

nessun altro procedimento? anche una routine che funzioni ?

Emanuele Zeppieri

unread,
Dec 17, 2011, 10:23:39 AM12/17/11
to
On Dec 15, 6:18 pm, capsula <___@___.___> wrote:

> [...]
> purtroppo non credo di poter compilare o aggiungere moduli al perl sul
> server.
>
> il cgi va eseguito sui server tophost partendo da una pagina web
>
> nessun altro procedimento? anche una routine che funzioni ?

Se segui il primo link che ti ha passato Andrea:
<http://www.perl.it//documenti/faq/view.html?pag=4&faq=4>

vedrai la soluzione che viene suggerita per prima (che è anche la più
semplice) non richiede alcun modulo CPAN, ma utilizza semplicemente i
builtin sprintf e/o printf:
http://perldoc.perl.org/functions/sprintf.html

Ciao!

Emanuele Zeppieri

unread,
Dec 18, 2011, 11:14:07 AM12/18/11
to
On Dec 15, 4:19 pm, capsula <___@___.___> wrote:

> Esempio :
>
> cifra = 51,645(689) > valore in euro 51,65 (arrotondato per eccesso)
>
> cifra = 25,822(844) > valore in euro 25,82(arrotondato per difetto)
>
> Non trovo nulla nelle opzioni dei comandi sprintf dove ho cercato.

Scusa non avevo letto che avevi già provato ad utilizzare sprintf.

Comunque il suo uso non dovrebbe presentare alcun problema, come puoi
vedere da questi esempi riferiti proprio i tuoi dati di test:

$ perl -E 'say sprintf "%.2f", 51.645689'
51.65

$ perl -E 'say sprintf "%.2f", 25.822844'
25.82

Se stai avendo difficoltà facci sapere.

capsula

unread,
Dec 19, 2011, 6:16:47 AM12/19/11
to
No, ho risolto appunto con sprintf. Da qualche parte avevo letto che non
c'è da fidarsi dell'approssimazione di base di perl e non mi fidavo
troppo delle funzioni base.
ho fatto un bel po di prove e sembra funzionare il criterio base con l'euro.
lo script mi serve per calcolare importi in euro che vanno sempre prima
approssimati al centesimo prima di operare la successiva operazione,
come farebbe un ragioniere passo dopo passo e non un matematico che
arrotonda alla fine.

c'è un modo per dichiarare una variabile sempre approssimata alla
seconda cifra dopo ogni operazione senza scrivere l'istruzione
successiva di arrotondamento ogni volta?




Emanuele Zeppieri

unread,
Dec 19, 2011, 3:25:15 PM12/19/11
to
On Dec 19, 12:16 pm, capsula <___@___.___> wrote:

> Da qualche parte avevo letto che non
> c'è da fidarsi dell'approssimazione di base di perl e non mi fidavo
> troppo delle funzioni base.

Puoi fidarti ciecamente, o almeno quanto ti fidi delle funzioni
(s)printf della libreria C stdio con la quale è stato compilato il tuo
perl.

> ho fatto un bel po di prove e sembra funzionare il criterio base con l'euro.
> lo script mi serve per calcolare importi in euro che vanno sempre prima
> approssimati al centesimo prima di operare la successiva operazione,
> come farebbe un ragioniere passo dopo passo e non un matematico che
> arrotonda alla fine.
>
> c'è un modo per dichiarare una variabile sempre approssimata alla
> seconda cifra dopo ogni operazione senza scrivere l'istruzione
> successiva di arrotondamento ogni volta?

Certamente, con tie() puoi farlo diventare completamente trasparente:

use strict;
use warnings;
use v5.10;

package Euro;

sub TIESCALAR { bless \my $rounded_value, shift }
sub FETCH { ${ shift() } }
sub STORE {
my $self = shift;
$$self = sprintf '%.2f', shift
}

package main;

tie my $value, 'Euro';

# Ed ora ogni valore assegnato a $value verrà automagicamente
arrotondato

$value = 51.645689;
say $value; # 51.65

$value = 25.822844;
say $value; # 25.82

__END__

Riferimenti:
http://perldoc.perl.org/perltie.html
http://perldoc.perl.org/functions/tie.html

Altrimenti se sei disposto a sacrificare la trasparenza a favore di
una soluzione più immediata, puoi cavartela con una semplice
subroutine:

sub round_euro { sprintf '%.2f', shift }

Detto tutto questo, mi sento di consigliarti di seguire il metodo dei
matematici piuttosto che quello dei ragionieri.
Ma accetto che mi si risponda che non sono affari miei ;-)

Ciao.

capsula

unread,
Dec 20, 2011, 11:29:53 AM12/20/11
to
Mi studio tutto, grazie.

La procedura da ragioniere è quella che, per esempio, prevede per ogni
passo un importo da scrivere poi su un modulario e poi da questo partire
per l'operazione successiva.
In caso contrario operando in virgola mobile fino alla fine il cumulo di
questi arrotondamenti può dare un risultato diverso; questo perchè gli
avanzi e i difetti non si mediano esattamente. Si possono avere una
serie di operazioni di arrotondamento in difetto che riducono il
risultato finale o viceversa.
In un bilancio di una società o un calcolo di versamento di tasse può
creare molti guai. Non è una cosa capziosa.
0 new messages