Menu

Làm tròn số trong PHP: round(), floor() và ceil()

round($x, 2) làm tròn đến hai chữ số thập phân, floor() luôn làm tròn xuống và ceil() luôn làm tròn lên. Thêm intdiv(), toán tử %, ** để tính lũy thừa, abs(), max(), min() và random_int() để lấy số ngẫu nhiên.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

round($x) làm tròn đến số nguyên gần nhất, floor($x) luôn làm tròn xuống và ceil($x) luôn làm tròn lên. Truyền cho round() tham số thứ hai để chọn số chữ số thập phân: round(3.14159, 2) là 3.14.

Cả ba hàm đều trả về số thực (float), kể cả khi giá trị là số nguyên. var_dump(round(5)) in ra float(5), nên hãy ép kiểu bằng (int) khi bạn cần số nguyên.

Làm tròn đến 2 chữ số thập phân

Tham số thứ hai của round() là độ chính xác. Số dương làm tròn đến từng ấy chữ số sau dấu thập phân. Số âm làm tròn về bên trái dấu thập phân, tiện cho các con số ước lượng như "khoảng 1.200 lượt truy cập".

round(3.10, 2) in ra 3.1 vì số thực không hề biết bạn muốn bao nhiêu số 0. Khi con số được hiển thị trên trang (giá tiền, phần trăm), hãy định dạng nó: number_format() biến 3.1 thành "3.10" với number_format(3.1, 2), và sprintf('%.2f', $x) cũng làm được như vậy.

Làm tròn nửa lên, nửa xuống hoặc nửa về số chẵn

Mặc định round() làm tròn giá trị nửa ra xa số 0, đúng kiểu làm tròn mà đa số chúng ta học ở trường (四捨五入). Tham số thứ ba chọn quy tắc khác cho những giá trị nằm đúng giữa hai số.

PHP_ROUND_HALF_EVEN là "làm tròn kiểu ngân hàng": giá trị nửa đi về số chẵn gần nhất, nên khi làm tròn nhiều giá trị, tổng không bị trôi dần lên theo thời gian. Code kế toán thường cần cách này.

floor và ceil với số âm

floor() đi về phía âm vô cùng và ceil() đi về phía dương vô cùng. Với số âm, điều này hay làm người ta bất ngờ: floor(-3.5) là -4, không phải -3. Nếu bạn muốn cắt bỏ phần thập phân (cắt về phía 0, 切り捨て), hãy ép kiểu sang int.

Dòng phân trang là cách dùng kinh điển của ceil(): còn dư một phần tử thì vẫn cần thêm một trang.

Chia lấy phần nguyên và chia lấy dư

/ trả về số thực khi phép chia không chẵn, nên 7 / 2 là 3.5. Để chia lấy phần nguyên, dùng intdiv(), hàm này bỏ phần dư, và dùng % để lấy chính phần dư.

% chuyển cả hai toán hạng sang số nguyên trước, nên 7.5 % 2 là 1, và từ PHP 8.1 nó còn in ra Deprecated: Implicit conversion from float 7.5 to int loses precision. Dùng fmod() khi phần thập phân quan trọng. Chia cho 0 bằng /, intdiv() hoặc % sẽ ném ra DivisionByZeroError trong PHP 8, nên hãy kiểm tra số chia trước khi nó đến từ đầu vào.

Lũy thừa, căn, abs, max và min

** tính lũy thừa (pow() cũng vậy), sqrt() lấy căn bậc hai và abs() bỏ dấu. max() và min() nhận nhiều đối số hoặc một mảng.

** được tính từ phải sang trái, nên 2 ** 3 ** 2 nghĩa là 2 ** 9. Cặp max(0, min(100, $x)) là cách thường dùng để kẹp một giá trị giữa cận dưới và cận trên. M_PI chứa số pi nếu bạn cần tính với hình tròn.

Số ngẫu nhiên với random_int và rand

random_int($min, $max) trả về một số nguyên ngẫu nhiên, tính cả hai đầu. Kết quả thay đổi mỗi lần chạy, nên hãy nhấn Chạy vài lần.

Dùng random_int() cho mọi thứ liên quan đến bảo mật: mã đăng nhập, token, liên kết đặt lại mật khẩu. rand() và mt_rand() vẫn chạy và nhận cùng đối số ($min, $max), nhưng chuỗi số của chúng có thể đoán trước. Để xáo trộn và chọn ngẫu nhiên từ nguồn an toàn, PHP 8.2 thêm Random\Randomizer ($r->getInt(1, 6), $r->shuffleArray($a)).

Vì sao floor() đôi khi cho kết quả sai

Số thực được lưu ở dạng nhị phân, và nhiều giá trị thập phân (như 0.1) không lưu chính xác được. Phần lớn thời gian, khi in ra thì sai lệch này bị che đi, nhưng floor() và (int) không làm tròn mà cắt bỏ, nên một giá trị như 7.999999999 thành 7.

Khi cần số thập phân chính xác, như với tiền, hãy lưu theo đơn vị nguyên (xu dưới dạng số nguyên: 1999 thay vì 19.99) và chỉ chia khi hiển thị. Làm tròn đến độ chính xác hợp lý trước khi gọi floor() hoặc ceil(), như ở dòng cuối, cũng xử lý được phần lớn trường hợp.

Câu hỏi thường gặp

Làm sao làm tròn đến 2 chữ số thập phân trong PHP?

Truyền số chữ số thập phân ở tham số thứ hai: round(3.14159, 2) trả về 3.14. Hàm trả về số thực, nên để hiển thị với số chữ số thập phân cố định (3.10 thay vì 3.1), hãy dùng number_format($x, 2) hoặc sprintf('%.2f', $x).

Làm sao làm tròn xuống trong PHP?

floor($x) làm tròn xuống số nguyên nhỏ hơn gần nhất: floor(4.9) là 4 và floor(-4.1) là -5. Để bỏ phần thập phân theo hướng về 0, hãy ép kiểu bằng (int) $x, khi đó -4.9 thành -4.

Vì sao round() trong PHP trả về số thực?

round(), floor() và ceil() luôn trả về số thực, kể cả khi kết quả là số nguyên: var_dump(round(5)) in ra float(5). Bọc lời gọi trong (int) hoặc intval() khi bạn cần số nguyên, chẳng hạn để làm chỉ số mảng.

rand() và random_int() trong PHP khác nhau thế nào?

random_int(1, 6) dùng nguồn ngẫu nhiên an toàn về mật mã và là hàm nên dùng cho token, mã xác nhận và mọi thứ người dùng có thể thử đoán. rand() và mt_rand() nhanh hơn nhưng đoán trước được. Cả ba đều tính cả hai đầu của khoảng.

Làm sao lấy phần dư của phép chia trong PHP?

Dùng toán tử % cho số nguyên: 17 % 5 là 2. Kết quả mang dấu của toán hạng bên trái, nên -7 % 3 là -1. Với số thực, dùng fmod(7.5, 2), hàm này trả về 1.5.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu