aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Math.floor và Math.trunc: chọn đúng quy tắc khi dữ liệu có số âm

Suong Nguyen by Suong Nguyen
08/11/2026
in Đánh giá
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Một hàm gom tọa độ vào ô lưới chạy đúng với toàn bộ dữ liệu dương, rồi sai ngay khi người dùng kéo sang bên trái gốc tọa độ. Nguyên nhân có thể nằm ở việc dùng Math.trunc thay cho Math.floor. Cả hai trả về phần nguyên theo một quy tắc, nhưng chúng trả lời hai câu hỏi khác nhau.

Bài đối chiếu tài liệu ngày 08/11/2026 và chạy ví dụ bằng Node.js 24.18.1. Các tiêu chí so sánh là ý nghĩa phép tính, hành vi với số âm, kiểm soát đầu vào và khả năng đọc code. Bài không có benchmark và không kết luận API nào chạy nhanh hơn trên browser hoặc thiết bị di động.

Hai quy tắc trùng nhau trên số dương

Math.floor chọn số nguyên lớn nhất không vượt quá đầu vào. Math.trunc bỏ phần thập phân, tiến về phía 0. Vì thế, chỉ thử 2.7 sẽ không giúp phân biệt hai cách làm.

for (const x of [-2.7, -0.2, 0, 2.7]) {
  console.log(x, Math.floor(x), Math.trunc(x));
}
console.log(Object.is(Math.trunc(-0.2), -0));

Với -2.7, kết quả là -3 và -2. Với -0.2, chúng là -1 và -0; phép kiểm tra cuối trả true. Hai dòng còn lại cho cặp 0, 0 và 2, 2. Trong bài toán chỉ cần bỏ phần lẻ của một độ lệch, trunc có thể phù hợp; khi đang chia mặt phẳng thành các khoảng liên tiếp, floor thường diễn đạt đúng hơn.

So sánh bằng một hợp đồng ô lưới cụ thể

Giả sử mỗi ô rộng 10 đơn vị, gốc ở 0 và ô k chứa các điểm từ k * 10 đến trước (k + 1) * 10. Theo hợp đồng này, tọa độ -1 thuộc ô -1, tọa độ 0 thuộc ô 0 và tọa độ 10 thuộc ô 1. Không có tranh luận về tên hàm ở đây: chỉ cần kiểm tra hàm có đáp ứng các khoảng đã định nghĩa hay không.

function cellIndex(x, width) {
  if (!Number.isFinite(x) || !Number.isFinite(width) || width <= 0) {
    throw new RangeError('Expected finite x and positive finite width');
  }
  const ratio = x / width;
  if (!Number.isFinite(ratio)) throw new RangeError('Ratio overflow');
  const result = Math.floor(ratio);
  return result === 0 ? 0 : result;
}

for (const x of [-11, -10, -1, 0, 9, 10]) {
  console.log(x, cellIndex(x, 10));
}

Các chỉ số lần lượt là -2, -1, -1, 0, 0, 1. Thay floor bằng trunc sẽ đưa -1 về ô 0, trái với hợp đồng. Ví dụ chủ động chuẩn hóa -0 thành 0 ở kết quả vì không dùng dấu của số 0 để phân biệt ô.

Đây là minh họa số học, chưa nối vào canvas, bản đồ hay hệ tọa độ có phép biến đổi. Nếu tọa độ đi qua nhiều phép tính số thực, cần kiểm tra thêm điểm sát ranh giới; ví dụ này không tự giải quyết mọi sai số tích lũy.

Chi phí áp dụng và quyền kiểm soát

Cả hai API đều có sẵn trong JavaScript, nên ví dụ không thêm dependency hoặc cấu hình build. Phần công việc thực tế nằm ở xác định quy tắc: làm tròn xuống hay bỏ phần lẻ? Đặt tên helper theo nghiệp vụ như cellIndex giúp người review kiểm tra quy tắc ấy mà không phải đoán mục đích từ một phép chia.

Không dùng lựa chọn này để thay thế validation. Hai hàm vẫn có hành vi với NaN và vô cực; helper ở trên từ chối chúng vì một chỉ số ô hữu ích phải xuất phát từ đầu vào hữu hạn. Chuỗi '10' cũng bị từ chối thay vì được tự động coi như số.

Tránh mẹo bitwise khi chỉ cần bỏ phần lẻ

Một biểu thức như x | 0 có thể trông ngắn hơn trunc nhưng kéo theo phép chuyển về số nguyên 32 bit. Hãy thử:

console.log(Math.trunc(4294967296.5));
console.log(4294967296.5 | 0);

Hai kết quả là 4294967296 và 0. Đây là khác biệt về giá trị, không phải một tối ưu có thể áp dụng mù. Chọn một hàm có tên mô tả quy tắc giúp tránh thêm một giới hạn miền dữ liệu ngoài dự kiến.

Cách chọn và kiểm tra

Chọn floor khi hợp đồng cần cận nguyên phía dưới, như các khoảng ô lưới vừa nêu. Chọn trunc khi hợp đồng yêu cầu giữ phần nguyên về phía 0. Trong cả hai trường hợp, thêm ít nhất một số âm có phần lẻ, một điểm biên nguyên và một đầu vào không hợp lệ vào ca kiểm tra.

Đừng dùng kết quả trùng nhau trên số dương làm bằng chứng rằng hai API thay thế được nhau. Viết quy tắc đầu ra trước sẽ giúp việc chọn API trở thành bước trực tiếp, dễ kiểm tra.

Nguồn tham khảo

  • MDN: Math.floor
  • MDN: Math.trunc

Tags: JavaScriptNumberSo sánh API
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

String.replace và replaceAll: thay một lần hay mọi lần, có giữ nguyên ký tự $ không?

by Suong Nguyen
07/11/2026
0

So sánh thay chuỗi bằng pattern string và RegExp, đồng thời dùng replacer function để giữ nguyên nội dung thay thế có $&.

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Array.map và flatMap: giữ nhóm hay ghép thành một danh sách?

by Suong Nguyen
06/11/2026
0

So sánh map và flatMap bằng dữ liệu nhóm để thấy độ sâu làm phẳng, số phần tử đầu ra và giới hạn khi callback async.

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Promise.any và Promise.race: chờ thành công đầu tiên hay kết quả đầu tiên?

by Suong Nguyen
05/11/2026
0

So sánh any và race bằng promise điều khiển được, gồm lỗi đầu tiên, AggregateError và danh sách rỗng.

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Array.slice và splice: end index khác deleteCount thế nào?

by Suong Nguyen
04/11/2026
0

So sánh slice và splice bằng cùng một mảng để phân biệt khoảng lấy ra, số phần tử xóa, giá trị trả về và việc thay đổi mảng...

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native Platform.select: native và default được chọn theo thứ tự nào?
  • Phỏng vấn JavaScript: vì sao regex.test cùng chuỗi lại đổi kết quả?
  • Android TextView.setText(Int): số đếm có thể bị hiểu thành resource ID

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply