Как преобразовать число с плавающей точкой в ​​целое число в JavaScript? - PullRequest
972 голосов
/ 27 февраля 2009

Я хотел бы преобразовать число с плавающей точкой в ​​JavaScript. На самом деле, я бы хотел знать, как сделать ОБА из стандартных преобразований: путем усечения и округления И эффективно, а не путем преобразования в строку и анализа.

Ответы [ 14 ]

1376 голосов
/ 27 февраля 2009
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 );

Ссылка на математический объект


Примеры

Положительный
// 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
Отрицательный
// 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
Положительный - Большие числа
// 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
Отрицательный - Большие числа
// 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
282 голосов
/ 11 октября 2012

Оператор побитового ИЛИ

Побитовый или оператор может использоваться для усечения чисел с плавающей запятой, и он работает как для положительных, так и для отрицательных значений:

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

Результаты

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

Сравнение производительности?

Я создал JSPerf тест , который сравнивает производительность между:

  • Math.floor(val)
  • val | 0 по битам ИЛИ
  • ~~val по битам НЕ
  • parseInt(val)

, который работает только с положительными числами. В этом случае вы можете безопасно использовать побитовые операции, а также функцию Math.floor.

Но если вам нужен код для работы с положительными и отрицательными значениями , то побитовая операция является самой быстрой (ИЛИ предпочтительной). Этот другой тест JSPerf сравнивает то же самое, где совершенно очевидно, что из-за дополнительной проверки знака Math теперь самый медленный из четырех.

Примечание

Как указано в комментариях, операторы BITWISE работают со 32-разрядными целыми числами со знаком, поэтому будут преобразованы большие числа, например:

1234567890  | 0 => 1234567890
12345678901 | 0 => -539222987
92 голосов
/ 14 октября 2009

Примечание. Вы не можете использовать Math.floor() вместо усеченного, потому что Math.floor(-3.1) = -4, а не -3 !!

Правильная замена усечения будет:

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

    return Math.floor(value);
}
42 голосов
/ 11 января 2012

Двойной оператор поразрядно, а не может использоваться для усечения чисел с плавающей запятой. Другие упомянутые вами операции доступны через Math.floor, Math.ceil и Math.round.

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

Подробнее любезно предоставлено Джеймсом Падолси.

38 голосов
/ 27 февраля 2009

Для усечения:

var intvalue = Math.floor(value);

Для тура:

var intvalue = Math.round(value);
23 голосов
/ 27 сентября 2011

Вы можете использовать метод parseInt без округления. Будьте осторожны с пользовательским вводом из-за вариантов префикса 0x (шестнадцатеричный) и 0 (восьмеричный).

var intValue = parseInt(floatValue, 10);
17 голосов
/ 25 июля 2013

Смещение бита на 0, что эквивалентно делению на 1

// >> or >>>
2.0 >> 0; // 2
2.0 >>> 0; // 2
8 голосов
/ 14 октября 2009

В вашем случае, когда вам нужна строка в конце (для вставки запятых), вы также можете просто использовать функцию Number.toFixed (), однако это будет выполнять округление.

6 голосов
/ 11 июля 2013

Здесь много предложений. Побитовое ИЛИ кажется самым простым. Вот еще одно короткое решение, которое работает и с отрицательными числами, используя оператор по модулю. Это, вероятно, легче понять, чем побитовое ИЛИ:

intval = floatval - floatval%1;

Этот метод также работает с большими значениями, где ни '| 0', ни '~~', ни '>> 0' не работают правильно:

> n=4294967295;
> n|0
-1
> ~~n
-1
> n>>0
-1
> n-n%1
4294967295
5 голосов
/ 28 февраля 2016

Еще один возможный способ - использовать операцию 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

Приоритет побитовых операций меньше, чем приоритет математических операций, это полезно. Примерь https://jsfiddle.net/au51uj3r/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...