Làm cách nào để chuyển đổi số float thành toàn bộ số trong JavaScript?


1110

Tôi muốn chuyển đổi một số float thành toàn bộ số trong JavaScript. Trên thực tế, tôi muốn biết cách thực hiện CẢ HAI chuyển đổi tiêu chuẩn: bằng cách cắt ngắn và làm tròn. Và hiệu quả, không thông qua chuyển đổi thành một chuỗi và phân tích cú pháp.


83
Nếu bạn không biết điều đó, tất cả các số trong javascript đều là số float. Từ thông số kỹ thuật:
một số

6
4.3.20 Loại số: Loại Số là một tập hợp các giá trị đại diện cho các số. Trong ECMAScript, tập hợp các giá trị đại diện cho các giá trị IEEE 754 định dạng 64 bit bao gồm các giá trị đặc biệt của Not Not-a-Number (NaN), vô cực dương và vô cực âm.
một số

9
Có, Javascript không có loại "số nguyên" riêng biệt, nhưng vẫn không có gì lạ khi cần thực hiện chuyển đổi này. Chẳng hạn, trong ứng dụng của tôi, người dùng đã nhập một số (có thể bao gồm cả xu). Tôi đã phải cắt bớt xu và hiển thị w / dấu phẩy. Bước 1 là chuyển đổi sang int.
mcherm

1
cũng hữu ích: so sánh tốc độ của tất cả các phương pháp jsperf.com/math-floor-vs-math-round-vs-parseint/33
c ..

1
@karl: Nếu tôi chấp nhận đầu vào vào một trường, tôi có thể kiểm soát những ký tự tôi chấp nhận, nhưng tôi có thể thực hiện tất cả các loại xử lý trong Javascript, không chỉ chấp nhận đầu vào của người dùng. Thậm chí sau đó tôi có thể muốn nó cho những thứ như hỗ trợ dán.
mcherm

Câu trả lời:


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

Tham chiếu đối tượng toán học


Ví dụ

Tích cực
// 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
Tiêu cực
// 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
Số dương - Số lớn hơn
// 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
Số âm - Số lớn hơn
// 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
Như đã đề cập trong một câu trả lời khác, việc cắt ngắn an toàn tiêu cực có thể được thực hiện bằng cách sử dụng var intValue = ~~floatValue;. Nếu ký hiệu quá tối nghĩa với thị hiếu của bạn, chỉ cần ẩn nó trong một chức năng : function toInt(value) { return ~~value; }. (Điều này cũng chuyển đổi chuỗi thành số nguyên, nếu bạn quan tâm để làm như vậy.)
Keen

4
Sẽ upvote nếu câu trả lời này có ví dụ đầu vào / đầu ra.
J. Bộ giải mã ngẫu nhiên

7
Về nhận xét ~ ~ giới hạn giá trị ở các số nguyên có chữ ký 32 bit, trong khi Math.floor / ceil / round có thể xử lý tối đa 53 bit (Number.MAX_SAFE_INTEGER 9007199254740991). Điều này được đề cập trong câu trả lời dưới đây, nhưng nó đáng để nhắc lại ở đây cho những người đọc những bình luận này.
Giăng

2
Đọc từ bên dưới ở một số nơi: Math.trunc(val);Nhận xét vì đây là câu trả lời được chấp nhận
Old Badman Grey

Không hoạt động với độ chính xác chính xác cho các giá trị như2.3 - 2.3 % 1
Lapys

301

Toán tử bitwise OR

Một bitwise hoặc toán tử có thể được sử dụng để cắt các số liệu dấu phẩy động và nó hoạt động cho các mặt tích cực cũng như phủ định:

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

Các kết quả

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

So sánh hiệu suất?

Tôi đã tạo một thử nghiệm JSPerf để so sánh hiệu năng giữa:

  • Math.floor(val)
  • val | 0 bitwise HOẶC
  • ~~val bitwise KHÔNG
  • parseInt(val)

chỉ hoạt động với số dương. Trong trường hợp này, bạn an toàn khi sử dụng các thao tác bitwise cũng như Math.floorchức năng.

Nhưng nếu bạn cần mã của mình để làm việc với các mặt tích cực cũng như tiêu cực , thì thao tác bitwise là nhanh nhất (HOẶC là mã ưa thích). Bài kiểm tra JSPerf khác này so sánh giống nhau ở chỗ khá rõ ràng vì kiểm tra dấu hiệu bổ sung, Math hiện chậm nhất trong bốn bài.

Ghi chú

Như đã nêu trong các nhận xét, toán tử BITWISE hoạt động trên các số nguyên 32 bit đã ký, do đó, số lượng lớn sẽ được chuyển đổi, ví dụ:

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

@FabioPoloni: có siêu đơn giản và dường như các toán tử bitwise là nhanh nhất. Đặc biệt, toán tử OR luôn luôn nhanh nhất thường được khớp bởi các phép toán KHÔNG và Toán học mặc dù các phép toán cũng chậm nhất khi bạn phải hỗ trợ các số âm, bởi vì nó bổ sung thêm một kiểm tra ký hiệu số.
Robert Koritnik

9
@thefourtheye: Tất cả các hoạt động bitwise trừ dịch chuyển phải không dấu, hoạt động trên các số nguyên 32 bit đã ký. Do đó, sử dụng các phép toán bitwise trên các giá trị dấu phẩy động sẽ chuyển đổi chúng thành một số nguyên tước bỏ các chữ số sau dấu thập phân.
Robert Koritnik

3
Nếu bạn chỉ cần nó cho các số dương, thì Math.floor()sẽ nhanh hơn (ít nhất là theo lần chạy thử nghiệm đầu tiên của tôi trên Google Chrome, phiên bản 30.0.1599.101), mạnh mẽ hơn (vì nó không phụ thuộc vào cách các số được biểu thị theo bit, có thể thay đổi và có thể phá vỡ giải pháp bitwise này), và quan trọng nhất, rõ ràng hơn.
ma11hew28

8
Lưu ý rằng các toán tử bitwise hoạt động trên các số 32 bit. Chúng sẽ không hoạt động với số lượng quá lớn để phù hợp với 32 bit.
Kat

2
~~tốt hơn bởi vì nó là một toán tử đơn nguyên. 4.2|0+4bằng 4nhưng ~~4.2+4bằng8
Janus Troelsen

94

Lưu ý: Bạn không thể sử dụng Math.floor()thay thế cho cắt ngắn, bởi vì Math.floor(-3.1) = -4và không -3!!

Một thay thế chính xác cho cắt ngắn sẽ là:

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

    return Math.floor(value);
}

1
Điều đó phụ thuộc vào hành vi mong muốn cho số âm. Một số sử dụng cần số âm để ánh xạ tới giá trị âm hơn (-3,5 -> -4) và một số yêu cầu chúng ánh xạ tới số nguyên nhỏ hơn (-3,5 -> -3). Cái trước thường được gọi là "sàn". Từ "cắt ngắn" thường được sử dụng để mô tả một trong hai hành vi. Trong trường hợp của tôi, tôi chỉ cho nó ăn số âm. Nhưng nhận xét này là một cảnh báo hữu ích cho những người KHÔNG quan tâm đến hành vi số âm.
mcherm

28
@mcherm: Sau đó, họ dường như không hiểu thuật ngữ "cắt cụt" một cách chính xác. Truncate thực hiện chính xác như tên gọi của nó: nó cắt các chữ số. Nó không bao giờ (theo nghĩa chung) tương đương với sàn hoặc trần. vi.wikipedia.org/wiki/Truncation
Thanatos

5
Math.trunc(value)đã được thêm vào trong ECMAScript 6
4esn0k

2
floorvòng về phía vô cực, truncatevòng về không. ( ceilvòng về phía vô cực).
Peter Cordes

46

Một toán tử bit bit không gấp đôi có thể được sử dụng để cắt phao. Các hoạt động khác mà bạn đề cập là có sẵn thông qua Math.floor, Math.ceilMath.round.

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

Thêm chi tiết lịch sự của James Padolsey.


1
Đây có lẽ là một điều tồi tệ đối với mã sản xuất (vì nó tối nghĩa) nhưng nó chính xác là những gì tôi cần để chơi mã công cụ kết xuất phông chữ của mình <canvas>trong JS . Cảm ơn bạn!
Kragen Javier Sitaker

10
Điều này cũng có thể được thực hiện với n | 0.
Jay Doulass

17
Lưu ý rằng một trong hai phương thức (~ ~ n hoặc n | 0) chỉ hoạt động trên các số lên đến 2 ^ 31-1 hoặc 2147483647. 2147483648 trở lên sẽ trả về kết quả không chính xác; ví dụ: 2147483647 | 0 trả về -2147483648 và 4294967295 | 0 trả về -1, gần như chắc chắn không phải là điều bạn muốn.
Ed Bayiates

40

Đối với cắt ngắn:

var intvalue = Math.floor(value);

Đối với vòng:

var intvalue = Math.round(value);

6
Math.floor không cắt bớt các giá trị âm. Xem câu trả lời ở trên. Nếu không thì trả lời tốt đẹp.
oligofren

Nếu bạn quan tâm đến hiệu suất, tôi đã đặt một trường hợp thử nghiệm nhỏ ở đây: jsperf.com/dsafdgdfsaf/2 (var | 0 thắng tại đây).
Cybolic

25

Bạn có thể sử dụng phương thức parseInt để không làm tròn số. Hãy cẩn thận với đầu vào của người dùng do các tùy chọn tiền tố 0x (hex) và 0 (bát phân).

var intValue = parseInt(floatValue, 10);

1
Điều này thực sự hữu ích khi bạn chỉ muốn phần nguyên của một số thập phân, không làm tròn lên hoặc xuống, đó là những gì .round, .ceil và .floor đều làm.
Judah Gabriel Himango

1
... Ngay cả khi chỉ đơn giản là cắt ngắn, đây dường như là phương pháp chậm nhất. jsperf.com/float-to-int-conversion-comparison
Robert Koritnik

2
Luôn luôn chuyển giá trị thứ 2 cho parseInt để chỉ định cơ sở bạn mong đợi. Vì vậy, parseInt (floatValue, 10) để luôn nhận được căn cứ 10.
Tim Tonomall

3
Mặc dù điều này đã cũ, nhưng câu hỏi này dường như là một câu hỏi thường được hỏi, vì vậy tôi sẽ đặt câu hỏi này ở đây như một lời cảnh báo. Nếu giá trị sẽ được biểu diễn bằng ký hiệu "e" vì kích thước của nó, nó sẽ chỉ dẫn đến một chữ số, không phải là những gì được mong đợi. Ví dụ: parseInt(1000000000000000000000, 10);kết quả trong 1, không phải 1 000 000 000 000 000 000 000. Dù sao, câu hỏi rõ ràng không muốn " chuyển đổi thành chuỗi và phân tích cú pháp ", mặc dù điều đó tương đối nhỏ ...;)
Qantas 94 Nặng

4
@ Qantas94Heavy Lý do cho hành vi này là bởi vì parseInt()mong đợi một chuỗi không phải là một số như tham số đầu tiên của nó. Khi bạn chuyển số nguyên này, nó được chuyển đổi thành 1e21và sau đó parseIntphân tích chuỗi 1e21, kết quả là 1.
Olaf Dietsche

18

Bit dịch chuyển bằng 0, tương đương với chia cho 1

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

4
Lưu ý nhỏ: >> 0dường như chỉ hoạt động đối với số nguyên < 2 ^ 31-1>>> 0đối với số nguyên < 2 ^ 32-1 . Điều này trả về 0 cho các giá trị lớn hơn
Romuald Brunet

@RomualdBrunet, vâng, JavaScript xác định rõ ràng tất cả các hoạt động bitwise là hoạt động trên các số 32 bit. Đó là trong thông số kỹ thuật.
Alexis Wilke

Điều này hoạt động như Javascript chỉ hoạt động theo bitwise với số nguyên 32 bit (đã ký) như đã nêu trong câu trả lời ở trên. Vì vậy, bất kỳ hoạt động bit nào dường như không làm gì (như thay đổi cho 0, HOẶC với 0, VÀ với 1, gấp đôi KHÔNG) vẫn cần trình thông dịch Javascript để chuyển đổi giá trị thành int 32 bit.
FrankKrumnow

9

Trong trường hợp của bạn, khi bạn muốn một chuỗi cuối cùng (để chèn dấu phẩy), bạn cũng có thể chỉ sử dụng Number.toFixed()hàm, tuy nhiên, điều này sẽ thực hiện làm tròn.


7

Có rất nhiều gợi ý ở đây. OR bitwise dường như là đơn giản nhất cho đến nay. Đây là một giải pháp ngắn khác cũng hoạt động với các số âm cũng như sử dụng toán tử modulo. Có lẽ dễ hiểu hơn bitwise OR:

intval = floatval - floatval%1;

Phương pháp này cũng hoạt động với các số có giá trị cao trong đó cả '| 0' và '~ ~' cũng không '>> 0' hoạt động chính xác:

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

Nếu bạn tham khảo một câu trả lời khác, xin vui lòng thêm một tài liệu tham khảo cho nó hoặc phác thảo ngắn gọn ý tưởng của nó.
bertl

5

Để cắt ngắn :

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

Để làm tròn :

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

5

Một cách khả dĩ hơn - sử dụng thao tác 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

Ưu tiên của các phép toán bitwise ít hơn mức độ ưu tiên của các phép toán, nó rất hữu ích. Hãy thử trên https://jsfiddle.net/au51uj3r/


2

Nếu nhìn vào Mathđối tượng gốc trong JavaScript, bạn sẽ có được toàn bộ các hàm hoạt động trên các số và giá trị, v.v ...

Về cơ bản những gì bạn muốn làm là khá đơn giản và có nguồn gốc từ JavaScript ...

Hãy tưởng tượng bạn có số dưới đây:

const myValue = 56.4534931;

và bây giờ nếu bạn muốn làm tròn nó xuống số gần nhất, chỉ cần làm:

const rounded = Math.floor(myValue);

và bạn nhận được:

56

Nếu bạn muốn làm tròn số đó đến số gần nhất, chỉ cần làm:

const roundedUp = Math.ceil(myValue);

và bạn nhận được:

57

Ngoài ra, Math.roundchỉ cần làm tròn nó đến số cao hơn hoặc thấp hơn tùy thuộc vào số nào gần với số flot hơn.

Ngoài ra, bạn có thể sử dụng ~~phía sau số float, điều đó sẽ chuyển đổi một số float thành toàn bộ số.

Bạn có thể sử dụng nó như ~~myValue...


Hãy cẩn thận với ~~vì nếu số lớn hơn giới hạn int 32, nó sẽ thay đổi giá trị thành giá trị giới hạn 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

Tôi chỉ muốn chỉ ra rằng bạn muốn làm tròn mà không cần phải cắt xén. Bị mất một xu ít có khả năng hơn, vì 4.999452 * 100 được làm tròn sẽ cho bạn 5, một câu trả lời đại diện hơn.

Và trên hết, đừng quên làm tròn số của ngân hàng , đó là một cách để chống lại sự thiên vị hơi tích cực mà làm tròn thẳng mang lại - ứng dụng tài chính của bạn có thể yêu cầu nó.

Làm tròn Gaussian / ngân hàng trong JavaScript


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.