¿Cómo obtener la parte entera y decimal de un número?

98

Dado, digamos, 1,25 - ¿cómo obtengo "1" y "25" partes de este número?

Necesito verificar si la parte decimal es .0, .25, .5 o .75.

StackOverflowNewbie
fuente
¿Funcionará una simple explosión? $ splitDec = explotar (".", $ decimal); $ splitDec [0] ahora será el 1 y splitDec [1] ahora será el 25 de su ejemplo.
Matt
@Matt split()ha quedado obsoleto.
alex
@alex sí, lo olvidé. Estaba pensando en javascript. cambiado para explotar.
Matt
@Matt, split ha quedado obsoleto a partir de PHP 5.3 y en realidad toma una expresión regular como argumento, mientras que explotar toma una cadena. En este caso, se prefiere explotar ().
shelhamer
4
Tenga en cuenta que explode(".",1.10);daré 1 y 1, no 1 y 10
Michel

Respuestas:

177
$n = 1.25;
$whole = floor($n);      // 1
$fraction = $n - $whole; // .25

Luego compare con 1/4, 1/2, 3/4, etc.


En casos de números negativos, use esto:

function NumberBreakdown($number, $returnUnsigned = false)
{
  $negative = 1;
  if ($number < 0)
  {
    $negative = -1;
    $number *= -1;
  }

  if ($returnUnsigned){
    return array(
      floor($number),
      ($number - floor($number))
    );
  }

  return array(
    floor($number) * $negative,
    ($number - floor($number)) * $negative
  );
}

El $returnUnsignedlo para de hacer -1,25 a -1 y -0,25

Brad Christie
fuente
7
Como un lado, intval()o un elenco simple, ya que (int)podría ser más eficaz quefloor()
Jason McCreary
1
¿Cómo explica el suelo los negativos?
LanceH
@LanceH: No es así, pero puedes hacer que lo maneje con bastante facilidad con una bandera negativa.
Brad Christie
4
Esta respuesta es realmente inexacta a menos que agregue una ronda (). Suena tonto, lo sé, pero tiene que ver con la aritmética de números de punto flotante de bajo nivel. Vea aquí: stackoverflow.com/questions/3726721/php-math-precision
Matt James
Pruebe con 510,9, devuelve 0,89. Pero no puedo decir por qué.
T30
38

Este código lo dividirá por ti:

list($whole, $decimal) = explode('.', $your_number);

donde $ entero es el número entero y $ decimal tendrá los dígitos después del punto decimal.

Shelhamer
fuente
9
Tenga en cuenta que explode(".",1.10);daré 1 y 1, no 1 y 10
Michel
3
Esto se rompe y arroja una advertencia sobre el índice indefinido, si el número es un entero o no contiene una parte decimal.
Andreyco
1
Esto supone que el número no va a terminar representado en notación científica cuando se convierte en cadena. Si es un número realmente muy grande o realmente muy pequeño, este no será el caso y este método se romperá.
GordonM
20

Solo para ser diferente :)

list($whole, $decimal) = sscanf(1.5, '%d.%d');

CodePad .

Como beneficio adicional, solo se dividirá cuando ambos lados estén formados por dígitos.

alex
fuente
2
Éste no se rompe si el número no contiene una parte decimal. ¡Excelente!
Andreyco
Es bueno que esto genere dos enteros; en lugar de int y float.
foochow
1
Esto supone que el número no va a terminar representado en notación científica cuando se convierte en cadena. Si es un número realmente grande o muy pequeño, entonces este no será el caso y este método se romperá.
GordonM
18

El método floor () no funciona con números negativos. Esto funciona siempre:

$num = 5.7;
$whole = (int) $num;  // 5
$frac  = $num - $whole;  // .7

... también funciona para negativos (mismo código, número diferente):

$num = -5.7;
$whole = (int) $num;  // -5
$frac  = $num - $whole;  // -.7
el tío
fuente
8

un camino corto (use floor y fmod)

$var = "1.25";
$whole = floor($var);     // 1
$decimal = fmod($var, 1); //0.25

luego compare $ decimal con 0, .25, .5 o .75

mpalencia
fuente
¡Acepto esta respuesta! Está cerca de C # (a % 1)y maneja bien los números negativos.
Bitterblue
7

Lanzarlo como un int y restar

$integer = (int)$your_number;
$decimal = $your_number - $integer;

O simplemente para obtener el decimal para comparar

$decimal = $your_number - (int)$your_number
Dom
fuente
5

También hay una función fmod que se puede usar: fmod ($ my_var, 1) devolverá el mismo resultado, pero en algún momento con un pequeño error redondo.

ip512
fuente
3

PHP 5.4+

$n = 12.343;
intval($n); // 12
explode('.', number_format($n, 1))[1]; // 3
explode('.', number_format($n, 2))[1]; // 34
explode('.', number_format($n, 3))[1]; // 343
explode('.', number_format($n, 4))[1]; // 3430
Vasil Nikolov
fuente
2

Esta es la forma que uso:

$float = 4.3;    

$dec = ltrim(($float - floor($float)),"0."); // result .3
Serdar Değirmenci
fuente
1

El método de Brad Christie es esencialmente correcto, pero se puede escribir de manera más concisa.

function extractFraction ($value) 
{
    $fraction   = $value - floor ($value);
    if ($value < 0)
    {
        $fraction *= -1;
    }

    return $fraction;
}

Esto es equivalente a su método, pero más corto y, con suerte, más fácil de entender como resultado.

GordonM
fuente
1
$x = 1.24

$result = $x - floor($x);

echo $result; // .24
Stnfordly
fuente
1

Si puede contar con que siempre tendrá 2 lugares decimales, puede usar una operación de cadena:

$decimal = 1.25;
substr($decimal,-2);  // returns "25" as a string

No tengo idea de rendimiento, pero para mi caso simple, esto fue mucho mejor ...

Ben Barreth
fuente
Nota: si hace esto, al menos debería usar round ($ decimal, 2); primero para asegurarse de que solo tiene dos dígitos como decimal. Pero no puede usar esto si desea tener las matemáticas correctas o manejar el dinero.
Ulrik McArdle
0

Para evitar el decimal flotante adicional (es decir, 50.85 - 50 dan 0.850000000852), en mi caso solo necesito 2 decimales para centavos de dinero.

$n = 50.85;
$whole = intval($n);
$fraction = $n * 100 % 100;
fbaudet
fuente
0

Estaba teniendo dificultades para encontrar una manera de separar realmente la cantidad en dólares y la cantidad después del decimal. Creo que lo descubrí principalmente y pensé en compartir si alguno de ustedes tenía problemas.

Así que básicamente...

si el precio es 1234,44 ... el total sería 1234 y el decimal sería 44 o

si el precio es 1234.01 ... el total sería 1234 y el decimal sería 01 o

si el precio es 1234.10 ... todo sería 1234 y decimal sería 10

Etcétera

$price = 1234.44;

$whole = intval($price); // 1234
$decimal1 = $price - $whole; // 0.44000000000005 uh oh! that's why it needs... (see next line)
$decimal2 = round($decimal1, 2); // 0.44 this will round off the excess numbers
$decimal = substr($decimal2, 2); // 44 this removed the first 2 characters

if ($decimal == 1) { $decimal = 10; } // Michel's warning is correct...
if ($decimal == 2) { $decimal = 20; } // if the price is 1234.10... the decimal will be 1...
if ($decimal == 3) { $decimal = 30; } // so make sure to add these rules too
if ($decimal == 4) { $decimal = 40; }
if ($decimal == 5) { $decimal = 50; }
if ($decimal == 6) { $decimal = 60; }
if ($decimal == 7) { $decimal = 70; }
if ($decimal == 8) { $decimal = 80; }
if ($decimal == 9) { $decimal = 90; }

echo 'The dollar amount is ' . $whole . ' and the decimal amount is ' . $decimal;
Julie
fuente
-1

No he visto un módulo simple aquí ...

$number         = 1.25;
$wholeAsFloat   = floor($number);   // 1.00
$wholeAsInt     = intval($number);  // 1
$decimal        = $number % 1;      // 0.25

En este caso conseguir ambos $wholeAs?y $decimalno depender del otro. (Puede tomar 1 de las 3 salidas de forma independiente). He mostrado $wholeAsFloaty $wholeAsIntporquefloor() devuelve un número de tipo flotante aunque el número que devuelve siempre será entero. (Esto es importante si está pasando el resultado a un parámetro de función con sugerencia de tipo).

Quería que esto dividiera un número de punto flotante de horas / minutos, por ejemplo, 96,25, en horas y minutos por separado para una instancia de DateInterval como 96 horas y 15 minutos. Hice esto de la siguiente manera:

$interval = new \DateInterval(sprintf("PT%dH%dM", intval($hours), (($hours % 1) * 60)));

En mi caso, no me importaban los segundos.

Adambean
fuente
-3
val = -3.1234

fraction = abs(val - as.integer(val) ) 
Guido C
fuente
2
Hola, agregue un poco de explicación junto con el código, ya que ayuda a comprender su código. Las respuestas de solo código están mal vistas.
Bhargav Rao