rafa escribiste:Hola, un saludo a todos.
Tengo una página en perl donde me calcula unas cantidades pero me dan algunos errores en su calculo, ya que si pongo 2 decimales las cantidades no son correctas, no se si sera porque es flotante , la programacion es la siguiente :
open(FICHERO, "$cambio");
my $sumat, $sumat1, $sumat2, $sumat3, $sumat4, $sumat5, $sumat6, $sumat7;
@lineas = <FICHERO>;
foreach my $linea (@lineas){
my @sumana = split(/;/,$linea);
if (@sumana[1] =~ / /){
if (@sumana[3] !~ /TOTAL.COMANDANCIA/){
if (@sumana[3] !~ /TOTAL /){
$sumat = sprintf("%.2f",$sumat + $sumana[4]/$count2);
$sumat1 = sprintf("%.2f",$sumat1 + $sumana[5]/$count2);
$sumat2 = sprintf("%.2f",$sumat2 + $sumana[6]/$count2);
$sumat3 = sprintf("%.2f",$sumat3 + $sumana[8]/$count2);
$sumat4 = sprintf("%.2f",$sumat4 + $sumana[9]/$count2);
$sumat5 = sprintf("%.2f",$sumat5 + $sumana[10]/$count2);
$sumat6 = sprintf("%.2f",$sumat6 + $sumana[11]/$count2);
$sumat7 = sprintf("%.2f",$sumat7 + $sumana[12]/$count2);
}
}
}
}
Por ejemplo la cantida que da en $sumat1 es 6.36, cuando en realidad debe ser 8.20.
las cantidades totales son 24061 y 2932, que divididas dan 8.20.
Si le pongo 4 decimales da la cantidad correcta.
No se que pasa, os agradeciria me dieran una solucion, o que me de solamente números enteros.
Gracias anticipadas.
Que tal,
No obstante las recomendaciones que hace explorer, que son buenas prácticas, recomiendo AMPLIAMENTE hacer una "
Refactoración" del código, es decir, hacer un análisis a conciencia para reescribir el código de tal manera que sea mucho mas sencillo de leer y que tenga mucho mejor rendmiento.
En qué parte? Bueno como mencioné, aparte de los comentarios hechos por explorer, podrían haber algunos cambios al respecto:
- Código: Seleccionar todo
@lineas = <FICHERO>;
foreach my $linea (@lineas){
...
Cambiarlo por:
- Código: Seleccionar todo
while ( my $line = <FICHERO> ) { # puedes agregar defined() para mayor seguridad
...
}
- Código: Seleccionar todo
if (@sumana[1] =~ / /){
if (@sumana[3] !~ /TOTAL.COMANDANCIA/){
if (@sumana[3] !~ /TOTAL /){
$sumat = sprintf("%.2f",$sumat + $sumana[4]/$count2);
$sumat1 = sprintf("%.2f",$sumat1 + $sumana[5]/$count2);
$sumat2 = sprintf("%.2f",$sumat2 + $sumana[6]/$count2);
$sumat3 = sprintf("%.2f",$sumat3 + $sumana[8]/$count2);
$sumat4 = sprintf("%.2f",$sumat4 + $sumana[9]/$count2);
$sumat5 = sprintf("%.2f",$sumat5 + $sumana[10]/$count2);
$sumat6 = sprintf("%.2f",$sumat6 + $sumana[11]/$count2);
$sumat7 = sprintf("%.2f",$sumat7 + $sumana[12]/$count2);
}
}
}
Estamos de acuerdo que esto es completamente horrible cierto? podemos observar el patrón de una sumatoria en secuencia, es decir, en elementos secuenciales desde 1...7, entonces por qué no utilizar un simple y mortal array?
Y no olvidemos mencionar los horribles 3 if anidados, pudiendolos escribir en una sola sentencia ( con las previas indicaciones hechas nuevamente por explorer ):
- Código: Seleccionar todo
my @sumat;
$#sumatoria = 7; # recortamos el array a solo 7 índices, o sea 8 elementos
....
if ( $sumana[1] =~ / / and
$sumana[3] !~ /TOTAL.COMANDANCIA/) and
$sumana[3] !~ /TOTAL /)
{
my $cont = 4;
for ( 0..$#sumatoria ) {
$sumat[$_] = sprintf( "%.2f", $sumat[$_] +
$sumana[$cont++] / $count2 );
}
#incluso la sentencia anterior puede quedar en una sola línea, pero
#evitemos la parte "oscura" para mostrar un ejemplo mas claro.
}
Y bueno principalmente eso le daría todo un giro a tu programa... no solo en claridad, sino para mantenerlo.
Ahora bien hay varios puntos que en lo personal no entiendo... uno de ellos es por qué en el if la condición sobre $sumana[3] checa sobre la no existencia del patrón TOTAL y TOTAL.COMANDANCIA? eso en mi punto de vista es un poco ambiguo.
En fin, esas son mis recomendaciones de mi interpretación sobre tu problema.
Best regards,