[Résolu] Sprintf & Arrondi

Sprintf & Arrondi [Résolu] - Perl - Programmation

Marsh Posté le 07-10-2011 à 02:30:36    

Bonjour,
 
Le script ci-dessous fonctionne mais cependant j'ai une question:
 
Si mon pourcentage fait 39,62% il m'affiche 39%
Je voudrai l'arrondi à 40%
Si c'était 39,12% je voudrai qu'il m'affiche 39%
 
Est-ce possible?
 

Code :
  1. opendir(DIR, $DIR) or die "Can't open $DIR: $!";
  2.     my $SEARCH_FILE = "billing_$mday-$mon-$year";
  3.     my @bil = grep(/$SEARCH_FILE/,readdir(DIR));
  4.     closedir(DIR) or warn "Can't close $DIR: $!";
  5.     if (@bil > 0)    {
  6.         foreach my $file (@bil)    {
  7.             my ($i, $y, $z, $a, $b) = (0, 0, 0, 0, 0);
  8.             open (FILE, "<", $DIR.$file);
  9.             while (<FILE> )    {
  10.                 chomp $_;
  11.                 $_=~s/\&amp;/\&/g;
  12.                 $nbligne=keys(%hash)+1;
  13.                 my @tab=split(/;/,$_);
  14.                 if ($tab[11] == 490)    {
  15.                     next;
  16.                 }
  17.                 elsif (! $hash{$tab[0]."|".$tab[2]."|".$tab[3]."|".$tab[6]})    {
  18.                     $hash{$tab[0]."|".$tab[2]."|".$tab[3]."|".$tab[6]}=1;
  19.                     if (substr($tab[3],0,3) eq "DOA" or substr($tab[3],0,3) eq "DOJ" or substr($tab[3],0,3) eq "DOS" or substr($tab[3],0,3) eq "DOR" or substr($tab[3],0,3) eq "GMC" or substr($tab[3],0,3) eq "GMJ" or substr($tab[3],0,3) eq "GMB" or substr($tab[3],0,3) eq "GMD" or substr($tab[3],0,3) eq "CPV" or substr($tab[3],0,3) eq "PIN" )    {
  20.                         $y = $y + 1;
  21.                     }
  22.                     else    {
  23.                         if ($tab[5] != 0)    {
  24.                             $i = $i + 1;
  25.                         }
  26.                     }
  27.                     $z = $i + $y;
  28.                 }
  29.             }
  30.             if ($i == 0)    {
  31.                 print "\n__UNDEF__\n__END__";
  32.                 exit 0;
  33.             }
  34.             close (FILE);
  35.             $a = sprintf '%.2d%%', ($y/$z*100);
  36.             $b = sprintf '%.2d%%', ($i/$z*100);
  37.             $Message = $Message . "$mday_hier/$mon_hier/$year_hier\t$y($a)\t\t$i($b)\t\t$z\n";
  38.             print "$mday_hier/$mon_hier/$year_hier;$y;$i;$z\n";
  39.         }
  40.         foreach my $del (@bil)    {
  41.             unlink $DIR.$del;
  42.         }
  43.     }
  44.     # Vérification de la présence des données
  45.     else    {
  46.         print "\n$Err\n\n";
  47.         print "ERROR: NO BILLING FILES\n";
  48.         print "ERROR: __END__\n\n";
  49.         # send email
  50.         email_no_bil($To, $From, $Cc, $Bcc, $SubjectErr, $Message, $File);
  51.         exit;
  52.     }
  53. }


Message édité par Sethenssen le 07-10-2011 à 11:36:20
Reply

Marsh Posté le 07-10-2011 à 02:30:36   

Reply

Marsh Posté le 07-10-2011 à 11:04:11    

:hello:  
 

Code :
  1. sub round {
  2.  $_[0] > 0 ? int($_[0] + .5) : -int(-$_[0] + .5)
  3. }
  4.  
  5. print "number\tround\n";
  6. foreach (39.62 , 39.12) {
  7.     printf( "%.2f\t%d\n", $_, round($_) );
  8. }


number  round
39.62   40
39.12   39


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-10-2011 à 11:36:02    

Il est fort ce Gilou,
Perso je n'ai pas compris ce que tu as écris mais ça fonctionne au poil.
 
Encore merci !

Reply

Marsh Posté le 07-10-2011 à 11:42:23    

C'est l'opérateur ternaire des geeks qui posent problème ?
 
La traduction de la ligne :

$_[0] > 0 ? int($_[0] + .5) : -int(-$_[0] + .5)


est :

if ($_[0] > 0)
   int($_[0] + .5)
 else
   -int(-$_[0] + .5)


 
Et le 0,5 est la valeur classique qui permet de faire l'arrondi vers l'entier le plus proche.

Reply

Marsh Posté le 07-10-2011 à 11:58:35    

Code :
  1. if ($_[0] > 0) {
  2.   int($_[0] + .5)
  3. }
  4. else {
  5.   -int(-$_[0] + .5)
  6. }

car les accolades sont obligatoires en perl avec un if..else
 
Et pour être tout à fait complet,
$_[0] c'est pour utiliser directement la valeur passée a la subroutine, et éviter une recopie inutile de la valeur dans une variable temporaire.
$_[0] est le premier élément de la liste @_, et cette liste est celle des valeurs passée en paramètre a la subroutine lors de l'appel.
A+,


Message édité par gilou le 07-10-2011 à 12:01:55

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-10-2011 à 12:06:27    

Ok merci c'est plus clair  :jap:  
 
Ce qui n'était pas clair c'était le one-liner
Donc:
? signifie alors
: signifie sinon
 
Merci.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed