2011-03-25 20 views
14

En PHP (usando funciones integradas) Me gustaría convertir/formatear un número con decimal, de modo que solo se muestren los decimales que no sean cero. Sin embargo, otro requisito mío es que si se trata de un número sin un valor decimal, me gustaría mostrar ese cero. Ejemplos:PHP muestra solo decimales significativos (no cero)

9.000 -> 9.0 
9.100 -> 9.1 
9.120 -> 9.12 
9.123 -> 9.123 

rtrim($value, "0") casi funciona. El problema con rtrim es que deja 9.000 como 9.. sprintf() parecía un candidato, pero no pude obtener una cantidad variable de decimales. number_format() sirve para un propósito diferente, y eso fue todo lo que pude encontrar ...

Una vez más, me gustaría señalar que no estoy buscando soluciones caseras para esto, estoy buscando un camino para lograr esto usando la funcionalidad interna de PHP. Puedo escribir una función que lo logre fácilmente, así que sostenga respuestas como esa.

+2

¿Se preg_replace() cuentan funcionalidad PHP como interna? – Kaivosukeltaja

+0

Según lo que describes, creo que es equivalente a dejar siempre 1 número después del punto decimal (".") –

Respuesta

7

No creo que haya una manera de hacerlo. Una expresión regular es probablemente la mejor solución:

$value = preg_replace('/(\.[0-9]+?)0*$/', '$1', $value); 

Demostración:

php> $a = array('0.000', '0.0001', '0.0101', '9.000', '9.100', '9.120', '9.123'); 
php> foreach($a as $b) { echo $b . ' => ' . preg_replace('/(\.[0-9]+?)0*$/', '$1', $b)."\n"; } 
0.000 => 0.0 
0.0001 => 0.0001 
0.0101 => 0.0101 
9.000 => 9.0 
9.100 => 9.1 
9.120 => 9.12 
9.123 => 9.123 
+0

Esto no funciona, ya que "9.01" se convertiría en "91". Necesita un grupo! –

+0

Me pones en el camino correcto, aunque tu respuesta no es PHP válida (el orden de tus parámetros es incorrecto). La forma correcta de hacerlo, utilizando preg_replace es preg_replace ('/ (? Alex

+0

Creo que necesitas 'preg_replace ($ value '/ \.? 0 * $ /', '')' para manejar cosas como 123.4500 –

1

Fuera de la caja que no es posible porque tiene dos formas diferentes de tratar el fragmento de sus flotadores. Primero tendrá que determinar cuántos números distintos de cero hay en su fragmento y luego actuar en consecuencia con sprintf.

<?php 

$numbers = array(
    '9.000', 
    '9.100', 
    '9.120', 
    '9.123', 
); 

foreach ($numbers as $number) { 

    $decimals = strlen(str_replace('0','', array_pop(explode('.', $number)))); 
    $decimals = $decimals ?: 1; 
    echo $number . " => " . sprintf("%.{$decimals}f", $number); 

    echo "<br/>"; 

} 
2

Un cero al final es significativa:

  • Un valor de 9,0 indica, que el valor real es de más de 8,9 y menos de 9,1
  • Un valor de 9,00000 implica, que el el valor real es más de 8.99999 y menos de 9.00001

Por lo tanto, su requisito es bastante inusual. Esa es la razón por la cual no existe una función para hacer lo que quiere.

+2

volver a lo básico .. – DhruvPathak

+5

Esto es más para fines de visualización que la precisión científica. Sé que eso es lo que significa la significación, y es por eso que puse "no cero" entre paréntesis. Supongo que podría haber formulado mi pregunta mejor. – Alex

+0

Las reglas para dígitos significativos también son solo para fines de visualización. Durante el cálculo, se utiliza la mayor precisión posible. Solo cuando se muestre el resultado final, se redondeará a una precisión adecuada (para no implicar una precisión que la entrada nunca tuvo). – Oswald

5

¿No debería ser ?:

$value = preg_replace('~0*$~', '', $value); 

La sintaxis de PHP preg_replace es

mixed preg_replace (mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]]) 
+0

+1, esta es la única solución que hace lo que el OP solicitó. –

+0

No es válido para 9.120 – Thibault

+0

@Thibault - Su escritura '~ ([.] [0-9]) 0 * $ ~' era demasiado compleja, ver edición! –

2
<?php 
    $numbers = array(
     "9.000", 
     "9.100", 
     "9.120", 
     "9.123" 
    ); 
    foreach($numbers as $number) { 
     echo sprintf(
      "%s -> %s\n", 
      $number, 
      (float) $number == (int) $number ? number_format($number, 1) : (float) $number 
     ); 
    } 
?> 

Salida:

9.000 -> 9.0 
9.100 -> 9.1 
9.120 -> 9.12 
9.123 -> 9.123 
-1

Mi solución es dejar que php manejarlo como un número (es * 1) y luego tratarlo como una cadena (mi ex amplia que estaba usando porcentajes almacenados como un decimal con 2 cifras decimales):

printf('%s%% off', $value*1); 

Este salidas:

0.00 => 0% off 
0.01 => 0.01% off 
20.00 => 20% off 
20.50 => 20.5% off 
+0

No responde la pregunta – Ren

-2

rtrim (valor $ "0") casi funciona. El problema con rtrim es que deja 9,000 como 9.

Tan solo rtrim ($ value, "0.") y listo.

+1

-1, entonces '9,000' y' 90,000' se convertirían en '9' y no' 9.0' o '90.0'. –

+0

¿qué pasa con rtrim (rtrim ($ value, "0"), ".") –

+0

También $ value = (float) $ value funciona igual –

6

intentar algo como esto

$number = 2.00; 
echo floor_dec($number,$deg); 

    function floor_dec($number, $deg = null) 
    { 
     if ($deg == null) 
      return $number * 1000/1000; 
     else 
      return $number * pow(10, $deg)/pow(10, $deg); 
    } 

mostrará "2"

0

¿Qué tal

preg_replace(/\\.$/,'.0',rtrim($value,'0')) 
3

Si desea una solución integrada y que está utilizando una versión de PHP más tarde que 4.2 podría probar floatval():

echo floatval(9.200); 

impresiones

9.2 

pero

echo floatval(9.123); 

grabados

9.123 

espero que esto ayude.

0

Suponiendo que el número se codifica como fundido o en una cadena, aquí hay un enfoque de propósito general:

$value = is_numeric($value) ? strval($value + 0) : $value; 
Cuestiones relacionadas