Chuyển từ float sang int không làm tròn số trong Javascript (Number truncation in JS)

Kể từ ES6, javascript cũng cấp cho ta một hàm là Math.trunc() dùng để loại bỏ phần số lẻ trong kiểu float hay double, trả về một số int. Hàm này không làm tròn số đó để được số int, chỉ đơn giản là loại bỏ phần lẻ thôi. Cùng xem đoạn code phía dưới.

1
2
3
4
5
6
7
8
9
10
let truncationNumber;
const number = 30.6

// Old Way
truncationNumber = number < 0 ? Math.ceil(number) : Math.floor(number);
// 30

// ES6 Way
truncationNumber = Math.trunc(number);
// 30

Cách sử dụng Math.trunc()

1
2
3
4
5
6
7
8
9
10
Math.trunc(30.9); // 30
Math.trunc(30.8); // 30
Math.trunc(30.8); // 30
Math.trunc(30.6); // 30
Math.trunc(30.5); // 30
Math.trunc(30.4); // 30
Math.trunc(30.3); // 30
Math.trunc(30.2); // 30
Math.trunc(30.1); // 30
Math.trunc(-30.1); // -30

Như bạn thấy, Math.trunc() chỉ cắt từ dấu chấm và phía bên phải của dấu chấm sau đó vứt đi, không bận tâm bạn truyền vào số dương hay âm.

Với trường hợp bạn truyền vào chữ hay không phải là số, thì hàm này sẽ trả về như thế nào, cùng xem qua ví dụ.

1
2
3
4
5
Math.trunc('30.1'); // 30
Math.trunc('hello'); // NaN
Math.trunc(NaN); // NaN
Math.trunc(undefined); // NaN
Math.trunc(); // NaN

Cách sử dụng parseInt

Cũng tương tự, đây là kết quả khi dùng parseInt

1
2
3
4
5
6
parseInt(30.1); // 30
parseInt(-30.1); // -30
parseInt('30.1'); // 30
parseInt('hello'); // NaN
parseInt(undefined); // NaN
parseInt(); // NaN

Nên dùng Math.trunc() hay parseInt()

parseInt is mainly used for a string argument. So if you’re dealing with numbers, it’s way better to use Math.trunc().

If you’re curious, I wrote up a performance test comparing these two functions.

parseInt có tham số truyền vào là một string. Do đó khi bạn đang muốn xử lý số thì cách tốt nhất là sử dụng Math.trunc().

Nếu bạn tò mò, thì ghé thăm một bài viết khác của chị Samantha Ming https://jsperf.com/math-trunc-vs-parseint.

Một số lưu ý với parseInt

Có một số vấn đề tiềm ẩn với parseInt. Cơ bản là khi bạn truyền vào một tham số không phải là kiểu string parseInt sẽ đi convert tham số đó sang string bằng cách sử dụng cách gì đó đại loại như toString(). Đa phần trường hợp thì kết quả trả về bình thường nhưng với case này thì khác.

1
2
3
4
5
const number = 1000000000000000000000.5;

const result = parseInt(number);

console.log(result); // 1 <-- 😱

Điều gì đã xảy ra. Bởi vì tham số truyền vào của chúng ta không phải là string nên đầu tiên parseInt sẽ đi chuyển nó sang string.

1
2
3
4
5
6
const number = 1000000000000000000000.5;

// chỗ này mô phỏng cách covert của parseInt
const result = number.toString();

console.log(result); // "1e+21"

Lúc này nếu bạn thử truyền “1e+21” vào parseInt kết quả trả về sẽ là 1. Bởi vậy sẽ có chút hack não chỗ này nếu trường hợp của bạn rơi trúng y vào case này. Tớ nghĩ trường hợp ni tốt nhất nên sử dụng Math.trunc() thì tốt hơn cả.

1
2
3
4
5
const number = 1000000000000000000000.5;
const strNumber = number.toString();

Math.trunc(number); // 1e+21 -> 1000000000000000000000
Math.trunc(strNumber); // 1e+21 -> 1000000000000000000000

Bonus: Sử dụng toán tử bitwise

  • Double bitwise NOT ~~
1
console.log(~~80.6); // 80

Tác giả @Jorgert120

  • Bitwise OR |
1
console.log(80.6 | 0); // 80

Tác giả @mac_experts

Thử nghiệm

1
2
3
4
5
console.log(80.6 | 0); // 80
console.log(80.6 | 1); // 81
console.log(80.6 | 2); // 82
console.log(80.6 | 3); // 83
// ...

Trình duyệt hỗ trợ

Chắc trừ IE của bác Microsoft ra thôi, hoặc trừ thêm bạn sử dụng trình duyệt từ thời đồ đồng. Còn lại trình duyệt hiện đại đều support cả.

Xem thêm browser support tại https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Browser_compatibility

Nguồn

Bài viết được dịch từ https://medium.com/dailyjs/number-truncation-in-javascript-196c067b0d55 tác giả Samantha Ming.

Lúc dịch tớ sửa lại số trong ví dụ bằng số yêu thích :P.

 Comments
Comment plugin failed to load
Loading comment plugin