TransWikia.com

Redondeo decimal a centenos, decenas, centenas, millares, etc. segun X con PHP o SQL

Stack Overflow en español Asked on December 23, 2021

Hola a todos tengo un problema simple que no puedo resolver.

Tengo esta formular en EXCEL que calcula correcto el redondeo según el numero de profundidad X.
El numero base de ejemplo es 1.234,56 y la X que es la profundidad del redondeo para arriba va del 1 al 6 por eso llegamos de rendondia para arriba 1.234,56 a 10.000,00

Formular Excel ok, que tengo que pasar a PHP o SQL.

=ROUNDUP(1.234,56/(10^1);2)*(10^1) =  $1.234,60
=ROUNDUP(1.234,56/(10^2);2)*(10^2) =  $1.235,00
=ROUNDUP(1.234,56/(10^3);2)*(10^3) =  $1.240,00
=ROUNDUP(1.234,56/(10^4);2)*(10^4) =  $1.300,00
=ROUNDUP(1.234,56/(10^5);2)*(10^5) =  $2.000,00
=ROUNDUP(1.234,56/(10^6);2)*(10^6) = $10.000,00

Esta acá todo ok yo pase esta formular con PHP y SQL para que sea igual, pero no se comporta igual, ya que cuando X es mayor a 2 falla y redondo mal los números.
X es el numero que pongo dentro de la función POW(10,X) en PHP y SQL y en Excel su equivalente es (10^X)

Ejemplo PHP:

echo (round(1234.56/pow(10, 1),2,PHP_ROUND_HALF_EVEN)*pow(10, 1)); //1234.6
echo"<br>";
echo (round(1234.56/pow(10, 2),2,PHP_ROUND_HALF_EVEN)*pow(10, 2)); //1235
echo"<br>";
echo (round(1234.56/pow(10, 3),2,PHP_ROUND_HALF_EVEN)*pow(10, 3)); //1230
echo"<br>";
echo (round(1234.56/pow(10, 4),2,PHP_ROUND_HALF_EVEN)*pow(10, 4)); //1200
echo"<br>";
echo ((round(1234.56/pow(10, 5),2,PHP_ROUND_HALF_EVEN))*pow(10, 5)); //1000
echo"<br>";
echo ((round(1234.56/pow(10, 6),2,PHP_ROUND_HALF_EVEN))*pow(10, 6)); //0

Ejemplo MySQL (que tiene el mismo problema que PHP):

SELECT
ROUND((1234.56/pow(10,1)),2)*pow(10,1),
ROUND((1234.56/pow(10,2)),2)*pow(10,2),
ROUND((1234.56/pow(10,3)),2)*pow(10,3),
ROUND((1234.56/pow(10,4)),2)*pow(10,4),
ROUND((1234.56/pow(10,5)),2)*pow(10,5),
ROUND((1234.56/pow(10,6)),2)*pow(10,6)
;

Alguien me puede dara una mano con alguna formula PHP o SQL que sea valida para este fin ya que con esto que es igual en excel no se comporta igual en PHP o SQL.

Cualquier punta puede ser de mucha ayuda gracias.

2 Answers

La solución con PHP alternativa 1 :

function round_up($v, $p){
  $m = pow(10, abs($p)); 
  return $p<0 ? ceil($v/$m)*$m : ceil($v*$m)/$m;
}

// Ejemplo de uso con 1234.56
echo number_format( round_up(1234.56/pow(10,1),2)*pow(10,1), 2,'.',''); // 1234.60
echo '<br>';
echo number_format( round_up(1234.56/pow(10,2),2)*pow(10,2), 2,'.',''); // 1235.00
echo '<br>';
echo number_format( round_up(1234.56/pow(10,3),2)*pow(10,3), 2,'.',''); // 1240.00
echo '<br>';
echo number_format( round_up(1234.56/pow(10,4),2)*pow(10,4), 2,'.',''); // 1300.00
echo '<br>';
echo number_format( round_up(1234.56/pow(10,5),2)*pow(10,5), 2,'.',''); // 2000.00
echo '<br>';
echo number_format( round_up(1234.56/pow(10,6),2)*pow(10,6), 2,'.',''); //10000.00

Solucion PHP 2 mas simple:

echo (round(1234.56/pow(10, 1)+0.005,2,PHP_ROUND_HALF_EVEN)*pow(10, 1)); //1234.6
echo"<br>";
echo (round(1234.56/pow(10, 2)+0.005,2,PHP_ROUND_HALF_EVEN)*pow(10, 2)); //1235
echo"<br>";
echo (round(1234.56/pow(10, 3)+0.005,2,PHP_ROUND_HALF_EVEN)*pow(10, 3)); //1240
echo"<br>";
echo (round(1234.56/pow(10, 4)+0.005,2,PHP_ROUND_HALF_EVEN)*pow(10, 4)); //1300
echo"<br>";
echo ((round(1234.56/pow(10, 5)+0.005,2,PHP_ROUND_HALF_EVEN))*pow(10, 5)); //2000
echo"<br>";
echo ((round(1234.56/pow(10, 6)+0.005,2,PHP_ROUND_HALF_EVEN))*pow(10, 6)); //10000

Solucion PHP 3 media pero con formato decimal de 2 digitos

echo number_format((round(1234.56/pow(10, 1)+0.005,2,PHP_ROUND_HALF_EVEN)*pow(10, 1)),2,'.',''); //1234.60
echo"<br>";
echo number_format((round(1234.56/pow(10, 2)+0.005,2,PHP_ROUND_HALF_EVEN)*pow(10, 2)),2,'.',''); //1235.00
echo"<br>";
echo number_format((round(1234.56/pow(10, 3)+0.005,2,PHP_ROUND_HALF_EVEN)*pow(10, 3)),2,'.',''); //1240.00
echo"<br>";
echo number_format((round(1234.56/pow(10, 4)+0.005,2,PHP_ROUND_HALF_EVEN)*pow(10, 4)),2,'.',''); //1300.00
echo"<br>";
echo number_format(((round(1234.56/pow(10, 5)+0.005,2,PHP_ROUND_HALF_EVEN))*pow(10, 5)),2,'.',''); //2000.00
echo"<br>";
echo number_format(((round(1234.56/pow(10, 6)+0.005,2,PHP_ROUND_HALF_EVEN))*pow(10, 6)),2,'.',''); //10000.00

Answered by Sergio on December 23, 2021

A continuación un SQL en el cual podrás notar en cada paso como van quedando los valores hasta el final

SELECT

   potencia ProfundidadRedondeo, 
   /*valor,*/
   pow(10, potencia) ,
   valor/pow(10, potencia),
   ROUND(valor/pow(10, potencia), TOTALDECIMALES),
   ROUND(valor/pow(10, potencia)+(5/POW(10,TOTALDECIMALES+1)), TOTALDECIMALES) * pow(10, potencia) ElDatoFinal,
   5/POW(10,TOTALDECIMALES+1) /* ESTE VALOR ES EL QUE SE SUMA PARA REDONDEAR HACIA ARRIBA */

FROM
(
/* aqui cada  renglon que representa tu "X" */
select 1 potencia, 2 TOTALDECIMALES
union select 2, 2 TOTALDECIMALES
union select 3, 2 TOTALDECIMALES
union select 4, 2 TOTALDECIMALES
union select 5, 2 TOTALDECIMALES
union select 6, 2 TOTALDECIMALES
) algo
, (
/* Tu "numero base" de ejemplo */
select 1234.56 valor) valoreusa 
;

Solo te hacia falta sumar 0.005 para redondear hacia arriba. Es decir, el SQL que proporcionaste queda de la siguiente forma:

SELECT
ROUND((1234.56/pow(10,1))+0.005,2)*pow(10,1),
ROUND((1234.56/pow(10,2))+0.005,2)*pow(10,2),
ROUND((1234.56/pow(10,3))+0.005,2)*pow(10,3),
ROUND((1234.56/pow(10,4))+0.005,2)*pow(10,4),
ROUND((1234.56/pow(10,5))+0.005,2)*pow(10,5),
ROUND((1234.56/pow(10,6))+0.005,2)*pow(10,6)
;

Answered by RobertoLeOr on December 23, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP