Come faccio a convertire un numero float in un numero intero in JavaScript?


1110

Vorrei convertire un float in un numero intero in JavaScript. In realtà, vorrei sapere ENTRAMBI le conversioni standard: troncando e arrotondando. E in modo efficiente, non tramite la conversione in stringa e l'analisi.


83
Se non lo sapevi, tutti i numeri in JavaScript sono float. Dalle specifiche:
circa

6
4.3.20 Tipo di numero: il tipo Numero è un insieme di valori che rappresentano i numeri. In ECMAScript, l'insieme di valori rappresenta i valori IEEE 754 in formato 64 bit a doppia precisione, inclusi i valori speciali "Non un numero" (NaN), l'infinito positivo e l'infinito negativo.
circa il

9
Sì, Javascript non ha un tipo "integer" distinto, ma non è ancora insolito eseguire questa conversione. Ad esempio, nella mia applicazione gli utenti hanno digitato un numero (possibilmente includendo i centesimi). Ho dovuto troncare i centesimi e visualizzare w / virgole. Il passaggio 1 era convertire in int.
mcherm,

1
utile anche: confronto di velocità di tutti i metodi jsperf.com/math-floor-vs-math-round-vs-parseint/33
c ..

1
@karl: se accetto l'input in un campo, potrei essere in grado di controllare quali caratteri accetto, ma potrei fare tutti i tipi di elaborazione in Javascript, non solo accettare l'input dell'utente. Anche allora potrei volerlo per cose come il supporto della pasta.
mcherm,

Risposte:


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

Riferimenti a oggetti matematici


Esempi

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: numeri maggiori
// 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: numeri maggiori
// 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
Come menzionato in un'altra risposta, è possibile utilizzare un troncato sicuro per il negativo var intValue = ~~floatValue;. Se la notazione è troppo oscuro per i vostri gusti, basta nasconderlo in una funzione: function toInt(value) { return ~~value; }. (Questo converte anche le stringhe in numeri interi, se ti interessa farlo.)
Appassionato il

4
Voterebbe se questa risposta avesse input / output di esempio.
J. Random Coder,

7
Per quanto riguarda il commento ~~ limita il valore a numeri interi con segno a 32 bit, mentre Math.floor / ceil / round può gestire fino a 53-bit (Number.MAX_SAFE_INTEGER 9007199254740991). Questo è menzionato nella risposta qui sotto, ma vale la pena ripeterlo qui per coloro che leggono questi commenti.
Giovanni

2
Leggi dal basso in diversi punti: Math.trunc(val);commenta perché questa è la risposta accettata
Old Badman Gray

Non funziona con precisione esatta per valori come2.3 - 2.3 % 1
Lapys,

301

Operatore OR bit a bit

È possibile utilizzare un bit per bit o un operatore per troncare le cifre in virgola mobile e funziona sia per i positivi che per i negativi:

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

risultati

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

Confronto delle prestazioni?

Ho creato un test JSPerf che confronta le prestazioni tra:

  • Math.floor(val)
  • val | 0 bit a bit OR
  • ~~val NON bit a bit
  • parseInt(val)

funziona solo con numeri positivi. In questo caso sei sicuro di usare le operazioni bit a bit oltre alla Math.floorfunzione.

Ma se hai bisogno che il tuo codice funzioni con aspetti positivi e negativi , allora un'operazione bit a bit è la più veloce (O essendo quella preferita). Questo altro test JSPerf confronta lo stesso dove è abbastanza ovvio che a causa del controllo dei segni aggiuntivi Math è ora il più lento dei quattro.

Nota

Come indicato nei commenti, gli operatori BITWISE operano su numeri interi a 32 bit con segno, pertanto verranno convertiti grandi numeri, ad esempio:

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

@FabioPoloni: sì super semplice e sembra che gli operatori bit a bit siano i più veloci. Soprattutto l'operatore OR è sempre il più veloce spesso abbinato alle operazioni NOT e Math anche se le operazioni matematiche sono le più lente quando si devono supportare anche numeri negativi, perché aggiunge un ulteriore controllo del segno numerico.
Robert Koritnik,

9
@thefourtheye: tutte le operazioni bit a bit tranne lo spostamento a destra senza segno, funzionano su numeri interi a 32 bit con segno. Pertanto, l'utilizzo di operazioni bit per bit su valori in virgola mobile li convertirà in un numero intero rimuovendo le cifre dopo il punto decimale.
Robert Koritnik,

3
Se ne hai solo bisogno per numeri positivi, Math.floor()è più veloce (almeno secondo la mia esecuzione del tuo primo test JSPerf su Google Chrome, versione 30.0.1599.101), più robusto (perché non dipende da come i numeri sono rappresentati in bit, che può cambiare e eventualmente rompere questa soluzione bit per bit) e, soprattutto, più esplicita.
ma11hew28,

8
Si noti che gli operatori bit a bit operano su numeri a 32 bit. Non funzioneranno per numeri troppo grandi per adattarsi a 32 bit.
Kat,

2
~~è meglio perché è un operatore unario. 4.2|0+4uguale 4ma ~~4.2+4uguale8
Janus Troelsen

94

Nota: non è possibile utilizzare Math.floor()come sostituto di troncato, perché Math.floor(-3.1) = -4e non -3!!

Una sostituzione corretta per troncare sarebbe:

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

    return Math.floor(value);
}

1
Dipende dal comportamento desiderato per i numeri negativi. Alcuni usi richiedono numeri negativi per mappare al valore più negativo (-3,5 -> -4) e alcuni richiedono che siano mappati al numero intero più piccolo (-3,5 -> -3). Il primo è normalmente chiamato "piano". La parola "troncare" è spesso usata per descrivere entrambi i comportamenti. Nel mio caso, avrei solo dato da mangiare numeri negativi. Ma questo commento è un utile avvertimento per coloro a cui interessa il comportamento dei numeri negativi.
mcherm,

28
@mcherm: Quindi non sembrano comprendere correttamente il termine "troncare". Troncare fa esattamente come suggerisce il nome: tronca le cifre. Non è mai (in senso generale) equivalente a pavimento o soffitto. en.wikipedia.org/wiki/Truncation
Thanatos

5
Math.trunc(value)è stato aggiunto in ECMAScript 6
4esn0k

2
floorarrotondamenti verso -infinito, truncatearrotondamenti verso zero. ( ceilarrotonda verso + infinito).
Peter Cordes,

46

Un doppio operatore bit per bit non può essere utilizzato per troncare i float. Le altre operazioni che hai citato sono disponibili attraverso Math.floor, Math.ceile Math.round.

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

Maggiori dettagli per gentile concessione di James Padolsey.


1
Questa è probabilmente una brutta cosa da fare per il codice di produzione (dato che è oscuro) ma era esattamente quello di cui avevo bisogno per giocare a codice il mio <canvas>motore di rendering dei caratteri in JS . Grazie!
Kragen Javier Sitaker,

10
Questo può essere realizzato anche con n | 0.
Jay Douglass,

17
Si noti che uno dei metodi (~~ n oppure n | 0) funziona solo su numeri fino a 2 ^ 31-1 o 2147483647. 2147483648 o superiore restituirà un risultato errato; ad esempio, 2147483647 | 0 restituisce -2147483648 e 4294967295 | 0 restituisce -1, che quasi sicuramente non è quello che desideri.
Ed Bayiates,

40

Per troncare:

var intvalue = Math.floor(value);

Per round:

var intvalue = Math.round(value);

6
Math.floor non tronca i valori negativi. Vedi la risposta sopra. Altrimenti bella risposta.
oligofren,

Se sei interessato alle prestazioni, ho inserito un piccolo test case qui: jsperf.com/dsafdgdfsaf/2 (var | 0 vince qui).
Cybolic

25

È possibile utilizzare il metodo parseInt per nessun arrotondamento. Prestare attenzione all'input dell'utente a causa delle opzioni del prefisso 0x (esadecimale) e 0 (ottale).

var intValue = parseInt(floatValue, 10);

1
Questo è effettivamente utile quando vuoi solo la parte intera di un decimale, senza arrotondare per eccesso o per difetto, che è ciò che fanno .round, .ceil e .floor.
Judah Gabriel Himango,

1
... anche quando semplicemente troncando questo sembra essere il metodo più lento. jsperf.com/float-to-int-conversion-comparison
Robert Koritnik,

2
Passa sempre il secondo valore a parseInt per specificare quale base ti aspetti. Quindi, parseInt (floatValue, 10) per ottenere sempre la base 10.
Tim Tisdall,

3
Sebbene questa sia vecchia, questa domanda sembra essere una delle domande più frequenti, quindi la inserirò qui come avvertimento. Se il valore sarebbe rappresentato usando la notazione "e" a causa delle sue dimensioni, si otterrebbe solo una cifra, non ciò che ci si aspetta. Ad esempio, il parseInt(1000000000000000000000, 10);risultato è 1, non 1 000 000 000 000 000 000 000. Comunque, la domanda esplicitamente non voleva " convertirsi in una stringa e analizzare ", anche se è relativamente minore ...;)
Qantas 94 Heavy

4
@ Qantas94Heavy Il motivo di questo comportamento è perché si parseInt()aspetta una stringa e non un numero come primo parametro. Quando si passa questo numero intero, viene convertito in 1e21e quindi parseIntanalizza la stringa 1e21, che risulta 1.
Olaf Dietsche,

18

Spostamento bit di 0 che equivale alla divisione per 1

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

4
Piccola nota: >> 0sembra funzionare solo per numeri interi < 2 ^ 31-1 e >>> 0per numeri interi < 2 ^ 32-1 . Questo restituisce 0 per valori più grandi
Romuald Brunet,

@RomualdBrunet, sì, JavaScript definisce chiaramente tutte le operazioni bit a bit come operanti su numeri a 32 bit. Questo è nelle specifiche.
Alexis Wilke,

Questo funziona come Javascript fa operazioni bit per bit solo con numeri interi a 32 bit (firmati) come indicato in una risposta sopra. Quindi qualsiasi operazione di bit che sembra non fare nulla (come uno spostamento per 0, OR con 0 e AND con 1, doppio NOT) necessita ancora dell'interprete Javascript per convertire il valore in 32 bit int.
FrankKrumnow,

9

Nel tuo caso, quando vuoi una stringa alla fine (per inserire le virgole), puoi anche semplicemente usare la Number.toFixed()funzione, tuttavia, questo eseguirà l'arrotondamento.


7

Ci sono molti suggerimenti qui. L'OR bit a bit sembra di gran lunga il più semplice. Ecco un'altra breve soluzione che funziona anche con numeri negativi utilizzando l'operatore modulo. Probabilmente è più facile da capire rispetto all'OR bit a bit:

intval = floatval - floatval%1;

Questo metodo funziona anche con numeri di valore elevato in cui né '| 0' né '~~' né '>> 0' funzionano correttamente:

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

Se fai riferimento a un'altra risposta, aggiungi un riferimento o disegna brevemente la sua idea.
Bert

5

Per troncare :

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

Per arrotondare :

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

5

Un altro modo possibile: utilizzare l'operazione 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 priorità delle operazioni bit per bit è inferiore alla priorità delle operazioni matematiche, è utile. Prova su https://jsfiddle.net/au51uj3r/


2

Se si esamina l' Mathoggetto nativo in JavaScript, si ottiene che l'intero gruppo di funzioni funzioni su numeri e valori, ecc.

Fondamentalmente quello che vuoi fare è abbastanza semplice e nativo in JavaScript ...

Immagina di avere il numero seguente:

const myValue = 56.4534931;

e ora se vuoi arrotondarlo al numero più vicino, fai semplicemente:

const rounded = Math.floor(myValue);

e ottieni:

56

Se vuoi arrotondarlo al numero più vicino, fai semplicemente:

const roundedUp = Math.ceil(myValue);

e ottieni:

57

Anche Math.roundsolo arrotondarlo al numero più alto o più basso dipende da quale è più vicino al numero del flot.

Inoltre puoi usare ~~dietro il numero float, che convertirà un float in un numero intero.

Puoi usarlo come ~~myValue...


Si prega di fare attenzione con il ~~fatto che se il numero è maggiore del limite int 32, cambierà il valore nel valore 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

Voglio solo sottolineare che monetariamente vuoi arrotondare e non troncare. Essere fuori di un centesimo è molto meno probabile, dato che 4.999452 * 100 arrotondati ti darà 5, una risposta più rappresentativa.

E soprattutto, non dimenticare l'arrotondamento del banchiere , che è un modo per contrastare il pregiudizio leggermente positivo che dà l'arrotondamento diretto - la tua applicazione finanziaria potrebbe richiederlo.

Arrotondamento gaussiano / banchiere in JavaScript


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.