Como faço para converter um número flutuante em um número inteiro em JavaScript?

Eu gostaria de converter um float para um número inteiro em JavaScript. Na verdade, gostaria de saber como fazer BOTH das conversões padrão: truncando e arredondando. E de forma eficiente, não através da conversão para uma string e análise.

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 ); 

Referência de object matemático


Exemplos

Positivo

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

Negativo

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

Positivo – números maiores

 value = Number.MAX_SAFE_INTEGER/10 // 900719925474099.1 Math.floor(value) // 900719925474099 Math.ceil(value) // 900719925474100 Math.round(value) // 900719925474099 Math.trunc(value) // 900719925474099 parseInt(value) // 900719925474099 value | 0 // 858993459 ~~value // 858993459 value >> 0 // 858993459 value >>> 0 // 858993459 value - value % 1 // 900719925474099 

Negativo – números maiores

 value = Number.MAX_SAFE_INTEGER/10 * -1 // -900719925474099.1 Math.floor(value) // -900719925474100 Math.ceil(value) // -900719925474099 Math.round(value) // -900719925474099 Math.trunc(value) // -900719925474099 parseInt(value) // -900719925474099 value | 0 // -858993459 ~~value // -858993459 value >> 0 // -858993459 value >>> 0 // 3435973837 value - value % 1 // -900719925474099 

Operador bit a bit OU

Um operador bit a bit ou operador pode ser usado para truncar figuras de ponto flutuante e funciona para positivos e negativos:

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

Resultados

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

Comparação de desempenho?

Eu criei um teste JSPerf que compara o desempenho entre:

  • Math.floor(val)
  • val | 0 val | 0 bit a bit OU
  • ~~val bit a bit NÃO
  • parseInt(val)

que só funciona com números positivos. Neste caso, você está seguro para usar operações bitwise bem como a function Math.floor .

Mas se você precisar que seu código funcione com aspectos positivos e negativos , uma operação bit a bit será a mais rápida (ou a preferida). Este outro teste JSPerf compara o mesmo onde é bastante óbvio que, por causa da verificação de sinais adicionais, o Math é agora o mais lento dos quatro.

Nota

Como afirmado nos comentários, os operadores BITWISE operam em inteiros de 32 bits assinados, portanto, grandes números serão convertidos, exemplo:

 1234567890 | 0 => 1234567890 12345678901 | 0 => -539222987 

Nota: Você não pode usar Math.floor() como um substituto para truncate, porque Math.floor(-3.1) = -4 e não -3 !!

Um substituto correto para o truncamento seria:

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

Um operador double bitwise not pode ser usado para truncar flutuadores. As outras operações que você mencionou estão disponíveis através do Math.floor , Math.ceil e Math.round .

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

Mais detalhes cortesia de James Padolsey.

Para truncado:

 var intvalue = Math.floor(value); 

Por rodada:

 var intvalue = Math.round(value); 

Você pode usar o método parseInt para não arredondar. Tenha cuidado com a input do usuário devido às opções de prefixo 0x (hex) e 0 (octal).

 var intValue = parseInt(floatValue, 10); 

Bit shift por 0 que é equivalente a divisão por 1

 // >> or >>> 2.0 >> 0; // 2 2.0 >>> 0; // 2 

No seu caso, quando você quer uma string no final (para inserir vírgulas), você também pode simplesmente usar a function Number.toFixed (), no entanto, isso irá realizar arredondamentos.

Existem muitas sugestões aqui. O OR bit a bit parece ser, de longe, o mais simples. Aqui está outra solução curta que trabalha com números negativos, bem como usando o operador de módulo. É provavelmente mais fácil de entender do que o OR bit a bit:

 intval = floatval - floatval%1; 

Esse método também funciona com números de valor alto, em que nem ‘| 0’ nem ‘~~’ nem ‘>> 0’ funcionam corretamente:

 > n=4294967295; > n|0 -1 > ~~n -1 > n>>0 -1 > nn%1 4294967295 

Mais uma maneira possível – use a operação 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 

A prioridade das operações bit a bit é menor que a prioridade das operações matemáticas, é útil. Experimente em https://jsfiddle.net/au51uj3r/

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 arredondar :

 Math.round( 1.5 ); // 2 Math.round( 1.49 ); // 1 Math.round( -1.6 ); // -2 Math.round( -1.3 ); // -1 

Se você estiver usando angularjs, então solução simples da seguinte forma Em HTML Template Binding

{{val | number:0}}

converterá val em inteiro

passar com este link docs.angularjs.org/api/ng/filter/number

Eu só quero salientar que, monetariamente, você quer arredondar e não truncar. Estar fora por um centavo é muito menos provável, desde 4.999452 * 100 arredondado lhe dará 5, uma resposta mais representativa.

E além disso, não se esqueça do arredondamento do banqueiro , que é uma forma de combater o viés ligeiramente positivo que o arredondamento direto dá – sua aplicação financeira pode exigir isso.

Arredondamento de gaussiano / banqueiro em JavaScript