Como converter um número flutuante em um número inteiro em JavaScript?


1110

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


83
Se você não sabia, todos os números em javascript são flutuantes. A partir da especificação:
alguns

6
4.3.20 Tipo de número: O tipo Número é um conjunto de valores que representam números. No ECMAScript, o conjunto de valores representa os valores IEEE 754 de formato duplo de 64 bits, incluindo os valores especiais "Não-um-Número" (NaN), infinito positivo e infinito negativo.
alguns

9
Sim, o Javascript não possui um tipo "número inteiro" distinto, mas ainda não é incomum precisar fazer essa conversão. Por exemplo, no meu aplicativo, os usuários digitaram um número (possivelmente incluindo centavos). Eu tive que truncar os centavos e exibir com vírgulas. O passo 1 foi converter para int.
mcherm

1
também é útil: comparação rápida de todos os métodos jsperf.com/math-floor-vs-math-round-vs-parseint/33
c ..

1
@karl: Se eu estiver aceitando entrada em um campo, talvez eu consiga controlar quais caracteres eu aceito, mas eu poderia estar executando todos os tipos de processamento em Javascript, não apenas aceitando a entrada do usuário. Mesmo assim, talvez eu queira coisas como pasta de suporte.
Mcherm #

Respostas:


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

Referência de objeto matemático


Exemplos

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 maiores
// 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 maiores
// 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

82
Como mencionado em outra resposta, um truncado com segurança negativa pode ser feito usando var intValue = ~~floatValue;. Se a notação é demasiado obscuro para o seu gosto, apenas escondê-lo em uma função: function toInt(value) { return ~~value; }. (Isso também converte seqüências de caracteres em números inteiros, se você quiser fazê-lo.) #
31713 Keen

4
Voto positivo se esta resposta tiver exemplo de entrada / saída.
J. aleatória Coder

7
Em relação ao comentário, limita o valor para números inteiros assinados em 32 bits, enquanto Math.floor / ceil / round pode processar até 53 bits (Number.MAX_SAFE_INTEGER 9007199254740991). Isso é mencionado na resposta abaixo, mas vale a pena repetir aqui para quem lê esses comentários.
John

2
Leia abaixo em vários lugares: Math.trunc(val);Comentário porque esta é a resposta aceita
Old Badman Grey

Não funciona com precisão exata para valores como2.3 - 2.3 % 1
Lapys

301

Operador OR bit a bit

Um 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 OR bit a bit
  • ~~val NÃO bit a bit
  • parseInt(val)

isso funciona apenas com números positivos. Nesse caso, é seguro usar operações bit a bit e Math.floorfunções.

Mas se você precisar que seu código funcione com positivos e negativos , uma operação bit a bit é a mais rápida (OU é a preferida). Esse outro teste JSPerf compara o mesmo, onde é bastante óbvio que, devido à verificação adicional de sinais, o Math agora é o mais lento dos quatro.

Nota

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

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

@ FabioPoloni: sim, super simples e parece que os operadores bit a bit são os mais rápidos. Especialmente, o operador OR é sempre o mais rápido frequentemente correspondido pelas operações NOT e Math, embora as operações Math sejam as mais lentas quando você também precisa suportar números negativos, porque adiciona uma verificação adicional do sinal numérico.
precisa saber é o seguinte

9
@thefourtheye: Todas as operações bit a bit, exceto o shift direito não assinado, funcionam com números inteiros de 32 bits assinados. Portanto, o uso de operações bit a bit em valores de ponto flutuante os converterá em um número inteiro retirando dígitos após o ponto decimal.
Robert Koritnik 02/02

3
Se você precisar apenas de números positivos, Math.floor()é mais rápido (pelo menos de acordo com a execução do seu primeiro teste JSPerf no Google Chrome, versão 30.0.1599.101), mais robusto (porque não depende de como os números são representados em bits, que pode mudar e possivelmente quebrar essa solução bit a bit) e, mais importante, mais explícita.
ma11hew28

8
Observe que os operadores bit a bit operam em números de 32 bits. Eles não funcionam com números grandes demais para caber em 32 bits.
Kat

2
~~é melhor porque é um operador unário. 4.2|0+4igual 4mas ~~4.2+4igual8
Janus Troelsen

94

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

Uma substituição correta para truncar seria:

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

    return Math.floor(value);
}

1
Isso depende do comportamento desejado para números negativos. Alguns usos precisam de números negativos para mapear para o valor mais negativo (-3,5 -> -4) e alguns exigem que eles sejam mapeados para o número inteiro menor (-3,5 -> -3). O primeiro é normalmente chamado de "andar". A palavra "truncar" é frequentemente usada para descrever qualquer um dos comportamentos. No meu caso, eu só iria alimentar números negativos. Mas esse comentário é um aviso útil para quem se importa com o comportamento numérico negativo.
Mcherm 16/10/09

28
@mcherm: Então eles não parecem entender o termo "truncar" corretamente. Truncar faz exatamente como o nome indica: trunca dígitos. Nunca é (no sentido geral) equivalente a piso ou teto. en.wikipedia.org/wiki/Truncation
Thanatos

5
Math.trunc(value)foi adicionado no ECMAScript 6
4esn0k

2
floorarredonda para -in infinito, truncatearredonda para zero. ( ceilarredonda para + infinito).
Peter Cordes

46

Um operador não bit a bit duplo pode ser usado para truncar flutuadores. As outras operações que você mencionou estão disponíveis através de Math.floor, Math.ceile Math.round.

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

Mais detalhes cortesia de James Padolsey.


1
Provavelmente, isso é uma coisa ruim a se fazer para o código de produção (já que é obscuro), mas era exatamente o que eu precisava para executar o código de código do meu <canvas>mecanismo de renderização de fontes em JS . Obrigado!
Kragen Javier Sitaker

10
Isso também pode ser realizado com n | 0
Jay Douglass

17
Observe que o método (~~ n ou n | 0) funciona apenas em números de até 2 ^ 31-1 ou 2147483647. 2147483648 ou superior retornará um resultado incorreto; por exemplo, 2147483647 | 0 retorna -2147483648 e 4294967295 | 0 retorna -1, que quase definitivamente não é o que você deseja.
Ed Bayiates #

40

Para truncar:

var intvalue = Math.floor(value);

Para rodada:

var intvalue = Math.round(value);

6
Math.floor não trunca valores negativos. Veja a resposta acima. Caso contrário, boa resposta.
Oligofren

Se você está interessado em desempenho, coloquei um pequeno caso de teste aqui: jsperf.com/dsafdgdfsaf/2 (var | 0 vence aqui).
Cybolic

25

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

var intValue = parseInt(floatValue, 10);

1
Isso é realmente útil quando você deseja apenas a parte inteira de um decimal, sem arredondar para cima ou para baixo, que é o que .round, .ceil e .floor todos fazem.
Judah Gabriel Himango

1
... mesmo quando simplesmente truncar, esse parece ser o método mais lento. jsperf.com/float-to-int-conversion-comparison
Robert Koritnik: 11/11/12

2
Sempre passe o segundo valor para parseInt para especificar qual base você espera. Então, parseInt (floatValue, 10) para obter sempre base 10.
Tim Tisdall

3
Embora isso seja antigo, essa pergunta parece ser uma pergunta muito frequente, então colocarei isso aqui como um aviso. Se o valor for representado usando a notação "e" devido ao seu tamanho, resultará apenas em um dígito, não no esperado. Por exemplo, parseInt(1000000000000000000000, 10);resulta em 1, não em 1 000 000 000 000 000 000 000 000. De qualquer forma, a pergunta explicitamente não queria " converter para uma string e analisar ", embora isso seja relativamente menor ...;)
Qantas 94 Heavy

4
@ Qantas94Heavy A razão para esse comportamento é porque parseInt()espera que uma string não seja um número como seu primeiro parâmetro. Quando você passar este número inteiro, ele é convertido para 1e21e, em seguida, parseIntanalisa a cadeia 1e21, o que resulta em 1.
Olaf Dietsche

18

Deslocamento de bits por 0, o que equivale à divisão por 1

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

4
Nota pequena: >> 0parece funcionar apenas para números inteiros < 2 ^ 31-1 e >>> 0para números inteiros < 2 ^ 32-1 . Isso retorna 0 para valores maiores
Romuald Brunet

@RomualdBrunet, sim, o JavaScript define claramente todas as operações bit a bit como operando em números de 32 bits. Isso está nas especificações.
Alexis Wilke

Isso funciona como o Javascript faz operações bit a bit apenas com números inteiros de 32 bits (assinados), conforme indicado na resposta acima. Portanto, qualquer operação de bit que pareça não fazer nada (como uma mudança para 0, OR com 0 e AND com 1, NÃO) ainda precisa do interpretador Javascript para converter o valor em 32 bits int.
precisa saber é o seguinte

9

No seu caso, quando você deseja uma sequência no final (para inserir vírgulas), também pode usar a Number.toFixed()função, no entanto, isso fará o arredondamento.


7

Há muitas sugestões aqui. O OR bit a bit parece ser o mais simples de longe. Aqui está outra solução curta que funciona com números negativos, também usando o operador de módulo. Provavelmente é mais fácil entender do que o OR bit a bit:

intval = floatval - floatval%1;

Este método também funciona com números de alto valor, onde nem '| 0' nem '~~' nem '>> 0' funcionam corretamente:

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

Se você se referir a outra resposta, adicione uma referência a ela ou faça um breve esboço de sua ideia.
22813 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 arredondar :

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

5

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/


2

Se olhar para um Mathobjeto nativo em JavaScript, você obtém todo o conjunto de funções para trabalhar com números e valores, etc ...

Basicamente, o que você quer fazer é bastante simples e nativo em JavaScript ...

Imagine que você tem o número abaixo:

const myValue = 56.4534931;

e agora, se você quiser arredondá-lo para o número mais próximo, basta:

const rounded = Math.floor(myValue);

e você obtém:

56

Se você quiser arredondar para o número mais próximo, faça o seguinte:

const roundedUp = Math.ceil(myValue);

e você obtém:

57

Também Math.roundapenas arredondá-lo para um número maior ou menor depende de qual deles está mais próximo do número do flot.

Também é possível usar ~~atrás do número do flutuador, que converterá um flutuador em um número inteiro.

Você pode usá-lo como ~~myValue...


Por favor, tenha cuidado com o ~~porque, se o número for maior que o limite int 32, ele mudará o valor para o valor limite 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


0

Eu só quero ressaltar que monetariamente você deseja arredondar, e não truncar. É muito menos provável que você gaste um centavo, pois 4.999452 * 100 arredondado fornecerá 5, uma resposta mais representativa.

Além disso, não se esqueça do arredondamento dos banqueiros , que é uma maneira de combater o viés levemente positivo que o arredondamento direto oferece - seu aplicativo financeiro pode exigir isso.

Arredondamento de gaussiano / banqueiro em JavaScript


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.