¿Cómo convierto un número flotante a un número entero en JavaScript?

1110

Me gustaría convertir un flotante a un número entero en JavaScript. En realidad, me gustaría saber cómo hacer AMBAS conversiones estándar: truncando y redondeando. Y de manera eficiente, no mediante la conversión a una cadena y el análisis.

mcherm
fuente
83
Si no lo sabía, todos los números en JavaScript son flotantes. A partir de la especificación:
algunos
66
4.3.20 Tipo de número: El tipo de número es un conjunto de valores que representan números. En ECMAScript, el conjunto de valores representa los valores IEEE 754 de formato de doble precisión de 64 bits, incluidos los valores especiales de "No es un número" (NaN), infinito positivo e infinito negativo.
algunos
99
Sí, Javascript no tiene un tipo "entero" distinto, pero todavía no es raro que necesite hacer esta conversión. Por ejemplo, en mi aplicación, los usuarios escribieron un número (posiblemente incluyendo centavos). Tuve que truncar los centavos y mostrar w / comas. El paso 1 fue convertir a int.
mcherm
1
también útil: comparación de velocidad de todos los métodos jsperf.com/math-floor-vs-math-round-vs-parseint/33
c ..
1
@karl: Si acepto la entrada en un campo, podría controlar qué caracteres acepto, pero podría estar haciendo todo tipo de procesamiento en Javascript, no solo aceptando la entrada del usuario. Incluso entonces, podría quererlo para cosas como la pasta de apoyo.
mcherm

Respuestas:

1609
var intvalue = Math.floor( floatvalue );
var intvalue = Math.ceil( floatvalue ); 
var intvalue = Math.round( floatvalue );

// `Math.trunc` was added in ECMAScript 6
var intvalue = Math.trunc( floatvalue );

Referencia de objeto matemático


Ejemplos

Positivo
// value=x        //  x=5          5<x<5.5      5.5<=x<6  

Math.floor(value) //  5            5            5
Math.ceil(value)  //  5            6            6
Math.round(value) //  5            5            6
Math.trunc(value) //  5            5            5
parseInt(value)   //  5            5            5
~~value           //  5            5            5
value | 0         //  5            5            5
value >> 0        //  5            5            5
value >>> 0       //  5            5            5
value - value % 1 //  5            5            5
Negativo
// value=x        // x=-5         -5>x>=-5.5   -5.5>x>-6

Math.floor(value) // -5           -6           -6
Math.ceil(value)  // -5           -5           -5
Math.round(value) // -5           -5           -6
Math.trunc(value) // -5           -5           -5
parseInt(value)   // -5           -5           -5
value | 0         // -5           -5           -5
~~value           // -5           -5           -5
value >> 0        // -5           -5           -5
value >>> 0       // 4294967291   4294967291   4294967291
value - value % 1 // -5           -5           -5
Positivo: números más grandes
// x = Number.MAX_SAFE_INTEGER/10 // =900719925474099.1

// value=x            x=900719925474099    x=900719925474099.4  x=900719925474099.5

Math.floor(value) //  900719925474099      900719925474099      900719925474099
Math.ceil(value)  //  900719925474099      900719925474100      900719925474100
Math.round(value) //  900719925474099      900719925474099      900719925474100
Math.trunc(value) //  900719925474099      900719925474099      900719925474099
parseInt(value)   //  900719925474099      900719925474099      900719925474099
value | 0         //  858993459            858993459            858993459
~~value           //  858993459            858993459            858993459
value >> 0        //  858993459            858993459            858993459
value >>> 0       //  858993459            858993459            858993459
value - value % 1 //  900719925474099      900719925474099      900719925474099
Negativo: números más grandes
// x = Number.MAX_SAFE_INTEGER/10 * -1 // -900719925474099.1

// value = x      // x=-900719925474099   x=-900719925474099.5 x=-900719925474099.6

Math.floor(value) // -900719925474099     -900719925474100     -900719925474100
Math.ceil(value)  // -900719925474099     -900719925474099     -900719925474099
Math.round(value) // -900719925474099     -900719925474099     -900719925474100
Math.trunc(value) // -900719925474099     -900719925474099     -900719925474099
parseInt(value)   // -900719925474099     -900719925474099     -900719925474099
value | 0         // -858993459           -858993459           -858993459
~~value           // -858993459           -858993459           -858993459
value >> 0        // -858993459           -858993459           -858993459
value >>> 0       //  3435973837           3435973837           3435973837
value - value % 1 // -900719925474099     -900719925474099     -900719925474099
sombra de Luna
fuente
82
Como se mencionó en otra respuesta, se puede hacer un truncamiento seguro negativo usando var intValue = ~~floatValue;. Si la notación es demasiado oscuro para sus gustos, simplemente esconderlo en una función: function toInt(value) { return ~~value; }. (Esto también convierte las cadenas en enteros, si lo desea).
Keen
44
Votaría si esta respuesta tuviera entrada / salida de ejemplo.
J. Random Coder
77
Con respecto al comentario ~~ limita el valor a enteros con signo de 32 bits, mientras que Math.floor / ceil / round puede manejar hasta 53 bits (Number.MAX_SAFE_INTEGER 9007199254740991). Esto se menciona en la respuesta a continuación, pero vale la pena repetirlo aquí para quienes lean estos comentarios.
John
2
Lea desde abajo en varios lugares: Math.trunc(val);Comente porque esta es la respuesta aceptada
Old Badman Gray
No funciona con precisión exacta para valores como2.3 - 2.3 % 1
Lapys
301

Operador OR a nivel de bit

Se puede usar un operador u bit a bit para truncar figuras de punto flotante y funciona tanto para positivos como para negativos:

function float2int (value) {
    return value | 0;
}

Resultados

float2int(3.1) == 3
float2int(-3.1) == -3
float2int(3.9) == 3
float2int(-3.9) == -3

¿Comparación de rendimiento?

He creado una prueba JSPerf que compara el rendimiento entre:

  • Math.floor(val)
  • val | 0 bitwise O
  • ~~val NO bit a bit
  • parseInt(val)

eso solo funciona con números positivos. En este caso, es seguro usar operaciones bit a bit como Math.floorfunción.

Pero si necesita que su código funcione con positivos y negativos , entonces una operación bit a bit es la más rápida (O es la preferida). Esta otra prueba JSPerf compara lo mismo donde es bastante obvio que debido a la comprobación adicional de signos, Math es ahora el más lento de los cuatro.

Nota

Como se indicó en los comentarios, los operadores BITWISE operan con enteros de 32 bits con signo, por lo tanto, se convertirán grandes números, por ejemplo:

1234567890  | 0 => 1234567890
12345678901 | 0 => -539222987
Robert Koritnik
fuente
@FabioPoloni: sí, muy simple y parece que los operadores bit a bit son los más rápidos. Especialmente, el operador OR es siempre el más rápido a menudo igualado por las operaciones NOT y Math, aunque las operaciones Math también son las más lentas cuando tiene que admitir números negativos, porque agrega una verificación adicional del signo de número.
Robert Koritnik
99
@thefourtheye: todas las operaciones bit a bit, excepto el desplazamiento a la derecha sin signo, funcionan en enteros de 32 bits con signo. Por lo tanto, el uso de operaciones bit a bit en valores de coma flotante los convertirá en un número entero que elimina los dígitos después del punto decimal.
Robert Koritnik
3
Si solo lo necesita para números positivos, Math.floor()es más rápido (al menos según mi ejecución de su primera prueba JSPerf en Google Chrome, versión 30.0.1599.101), más robusto (porque no depende de cómo se representan los números en bits, que puede cambiar y posiblemente romper esta solución bit a bit), y lo más importante, más explícito.
ma11hew28
8
Tenga en cuenta que los operadores bit a bit operan con números de 32 bits. No funcionarán para números demasiado grandes para 32 bits.
Kat
2
~~es mejor porque es un operador unario. 4.2|0+4igual 4pero ~~4.2+4igual8
Janus Troelsen
94

Nota: ¡No se puede usar Math.floor()como un reemplazo para truncar, porque Math.floor(-3.1) = -4y no -3!

Un reemplazo correcto para truncar sería:

function truncate(value)
{
    if (value < 0) {
        return Math.ceil(value);
    }

    return Math.floor(value);
}
Jackson
fuente
1
Eso depende del comportamiento deseado para los números negativos. Algunos usos necesitan números negativos para mapear al valor más negativo (-3.5 -> -4) y algunos requieren que se mapeen al entero más pequeño (-3.5 -> -3). El primero normalmente se llama "piso". La palabra "truncar" a menudo se usa para describir cualquier comportamiento. En mi caso, solo iba a alimentarlo con números negativos. Pero este comentario es una advertencia útil para aquellos que sí se preocupan por el comportamiento negativo de los números.
mcherm
28
@mcherm: Entonces no parecen entender el término "truncar" correctamente. Truncar hace exactamente como su nombre lo indica: trunca los dígitos. Nunca es (en el sentido general) equivalente a piso o techo. en.wikipedia.org/wiki/Truncation
Thanatos
55
Math.trunc(value)fue agregado en ECMAScript 6
4esn0k
2
floorredondea hacia -infinito, truncateredondea hacia cero. ( ceilredondea hacia + infinito).
Peter Cordes
46

Se puede usar un operador doble no bit a bit para truncar los flotadores. Las otras operaciones que usted ha mencionado están disponibles a través Math.floor, Math.ceily Math.round.

> ~~2.5
2
> ~~(-1.4)
-1

Más detalles cortesía de James Padolsey.

puntilla
fuente
1
Probablemente sea algo malo para el código de producción (ya que es oscuro), pero era exactamente lo que necesitaba para codificar el golf de mi <canvas>motor de representación de fuentes en JS . ¡Gracias!
Kragen Javier Sitaker
10
Esto también se puede lograr con n | 0.
Jay Douglass
17
Tenga en cuenta que cualquiera de los métodos (~~ n o n | 0) solo funciona en números hasta 2 ^ 31-1, o 2147483647. 2147483648 o superior devolverá un resultado incorrecto; por ejemplo, 2147483647 | 0 devuelve -2147483648 y 4294967295 | 0 devuelve -1, que casi definitivamente no es lo que desea.
Ed Bayiates
40

Para truncar:

var intvalue = Math.floor(value);

Por ronda:

var intvalue = Math.round(value);
Miguel
fuente
66
Math.floor no trunca los valores negativos. Ver respuesta arriba. De lo contrario, buena respuesta.
oligofren
Si está interesado en el rendimiento, he puesto un pequeño caso de prueba aquí: jsperf.com/dsafdgdfsaf/2 (var | 0 gana aquí).
Cybolic
25

Puede usar el método parseInt para no redondear. Tenga cuidado con la entrada del usuario debido a las opciones de prefijo 0x (hexadecimal) y 0 (octal).

var intValue = parseInt(floatValue, 10);
Graeme Wicksted
fuente
1
Esto es realmente útil cuando solo quieres la parte entera de un decimal, sin redondear hacia arriba o hacia abajo, que es lo que hacen .round, .ceil y .floor.
Judá Gabriel Himango
1
... incluso cuando simplemente se trunca, este parece ser el método más lento. jsperf.com/float-to-int-conversion-comparison
Robert Koritnik
2
Siempre pase el segundo valor a parseInt para especificar qué base espera. Entonces, parseInt (floatValue, 10) para obtener siempre la base 10.
Tim Tisdall
3
Aunque esto es viejo, esta pregunta parece ser una que se hace con bastante frecuencia, por lo que lo pondré aquí como advertencia. Si el valor se representaría usando la notación "e" debido a su tamaño, solo dará como resultado un dígito, no lo que se espera. Por ejemplo, parseInt(1000000000000000000000, 10);da como resultado 1, no 1 000 000 000 000 000 000 000. De todos modos, la pregunta explícitamente no quería " convertir a una cadena y analizar ", aunque eso es relativamente menor ...;)
Qantas 94 Heavy
44
@ Qantas94Heavy La razón de este comportamiento es porque parseInt()espera que una cadena no sea un número como primer parámetro. Cuando pasa este número entero, se convierte 1e21y luego parseIntanaliza la cadena 1e21, lo que da como resultado 1.
Olaf Dietsche
18

Desplazamiento de bits por 0, que es equivalente a la división por 1

// >> or >>>
2.0 >> 0; // 2
2.0 >>> 0; // 2
Prasanth
fuente
44
Pequeña nota: >> 0parece funcionar solo para enteros < 2 ^ 31-1 , y >>> 0para enteros < 2 ^ 32-1 . Esto devuelve 0 para valores mayores
Romuald Brunet
@RomualdBrunet, sí, JavaScript define claramente todas las operaciones bit a bit como operando en números de 32 bits. Eso está en las especificaciones.
Alexis Wilke
Esto funciona como Javascript realiza operaciones bit a bit solo con enteros de 32 bits (con signo) como se indica en una respuesta anterior. Por lo tanto, cualquier operación de bits que parece no hacer nada (como un cambio para 0, O con 0, Y con 1, doble NO) todavía necesita un intérprete de Javascript para convertir el valor a 32 bits int.
FrankKrumnow
9

En su caso, cuando desee una cadena al final (para insertar comas), también puede usar la Number.toFixed()función, sin embargo, esto realizará el redondeo.

Russell Leggett
fuente
7

Hay muchas sugerencias aquí. El OR bit a bit parece ser el más simple con diferencia. Aquí hay otra solución corta que también funciona con números negativos utilizando el operador de módulo. Probablemente sea más fácil de entender que el bit a bit O:

intval = floatval - floatval%1;

Este método también funciona con números de alto valor donde ni '| 0' ni '~~' ni '>> 0' funcionan correctamente:

> n=4294967295;
> n|0
-1
> ~~n
-1
> n>>0
-1
> n-n%1
4294967295
Juliane Holzt
fuente
Si se refiere a otra respuesta, agréguele una referencia o esboce brevemente su idea.
bertl
5

Para truncar :

// Math.trunc() is part of the ES6 spec
Math.trunc( 1.5 );  // returns 1
Math.trunc( -1.5 ); // returns -1
// Math.floor( -1.5 ) would return -2, which is probably not what you wanted

Para redondear :

Math.round( 1.5 );  // 2
Math.round( 1.49 ); // 1
Math.round( -1.6 ); // -2
Math.round( -1.3 ); // -1
Maquinilla de afeitar
fuente
5

Una forma más posible: utilice la operación XOR:

console.log(12.3 ^ 0); // 12
console.log("12.3" ^ 0); // 12
console.log(1.2 + 1.3 ^ 0); // 2
console.log(1.2 + 1.3 * 2 ^ 0); // 3
console.log(-1.2 ^ 0); // -1
console.log(-1.2 + 1 ^ 0); // 0
console.log(-1.2 - 1.3 ^ 0); // -2

La prioridad de las operaciones bit a bit es menor que la prioridad de las operaciones matemáticas, es útil. Pruebe en https://jsfiddle.net/au51uj3r/

Dmitry Kharitonov
fuente
2

Si busca un Mathobjeto nativo en JavaScript, obtiene todas las funciones para trabajar en números y valores, etc.

Básicamente, lo que quieres hacer es bastante simple y nativo en JavaScript ...

Imagina que tienes el siguiente número:

const myValue = 56.4534931;

y ahora si quieres redondearlo al número más cercano, simplemente haz lo siguiente:

const rounded = Math.floor(myValue);

y obtienes:

56

Si desea redondearlo al número más cercano, simplemente haga lo siguiente:

const roundedUp = Math.ceil(myValue);

y obtienes:

57

Además, Math.roundsimplemente redondearlo a un número mayor o menor depende de cuál esté más cerca del número de flotador.

También puede usar ~~detrás del número flotante, que convertirá un flotante en un número entero.

Puedes usarlo como ~~myValue...

Alireza
fuente
Tenga cuidado con el ~~porque si el número es mayor que el límite int 32, cambiará el valor al valor límite int 32.
Machado
1

//Convert a float to integer

Math.floor(5.95)
//5

Math.ceil(5.95)
//6

Math.round(5.4)
//5

Math.round(5.5)
//6

Math.trunc(5.5)
//5

//Quick Ways
console.log(5.95| 0)
console.log(~~5.95) 
console.log(5.95 >> 0)
//5

pk_code
fuente
0

Solo quiero señalar que monetariamente quieres redondear, y no truncar. Estar fuera por un centavo es mucho menos probable, ya que 4.999452 * 100 redondeado le dará 5, una respuesta más representativa.

Y además de eso, no se olvide del redondeo bancario , que es una forma de contrarrestar el sesgo ligeramente positivo que produce el redondeo directo: su aplicación financiera puede requerirlo.

Redondeo gaussiano / bancario en JavaScript

Gerard ONeill
fuente
0

Si está utilizando angularjs, entonces la solución simple de la siguiente manera en Enlace de plantilla HTML

{{val | number:0}}

convertirá val en entero

ve a través de este enlace docs.angularjs.org/api/ng/filter/number

Jameel Grand
fuente