Tôi đã có một chút tò mò về điều này. Math.random() đưa ra một giá trị trong phạm vi [0.0.1.0). Vậy giá trị lớn nhất có thể là gì? Nói cách khác, giá trị gấp đôi gần nhất với 1.0 nhỏ hơn 1.0 là bao nhiêu?Java: Math.random() Giá trị lớn nhất (gấp đôi chỉ dưới 1)
Trả lời
Java sử dụng 64-bit IEEE-754 đại diện, do đó số gần nhất nhỏ hơn một là về mặt lý thuyết 3FEFFFFFFFFFFFFF
trong đại diện thập lục phân, mà là 0 cho dấu, -1 cho số mũ, và 1,9999999999999997 cho câu hỏi 52 bit. Điều này tương đương với khoảng 0.9999999999999998
.
Tham chiếu: IEEE-754 Calculator.
Giá trị dương nhỏ nhất của một đôi là Double.MIN_NORMAL
. Vì vậy, số lớn nhất nhỏ hơn 1.0 là 1.0-Double.MIN_NORMAL
.
Double.MIN_NORMAL
bằng 2 -1022, vì vậy câu trả lời vẫn là cực kỳ gần 1.0. Bạn sẽ phải in giá trị của 1.0-Double.MIN_NORMAL
-308 chữ số thập phân trước khi bạn có thể nhìn thấy bất cứ điều gì nhưng một 9.
Rất tiếc, khi tôi mã hoá '1.0 - Double.MIN_NORMAL == 1.0' trong System.out.println, tôi nhận được sự thật. Nhưng khi tôi encase 0,9999999999999999 trong System.out.println, tôi nhận được sai. Vậy điều đó có nghĩa là 0,9999999999999999 là gấp đôi gần nhất? – Justin
Hum ... Không, vì vậy, MIN_NORMAL áp dụng cho giá trị _closest đến zero_ Đó là loại lỗi nhỏ nhất có thể trên các giá trị IEEE-754. Nhưng kể từ khi bạn di chuyển về phía 1, một số độ chính xác bị mất! – mjv
'System.out.println (Double.MinNormal)' cho 2.2250738585072014E-308. Khá nhỏ. – Justin
Số mà bạn muốn được trả lại bởi Math.nextAfter(1.0, -1.0)
.
Tên của hàm có phần sai. Math.nextAfter(a, 1.0)
trả về giá trị đôi nhất đó là lớn hơn a
(ví dụ, giá trị tiếp theo sau khi a
), và Math.nextAfter(a, -1.0)
trả về giá trị lớn nhất mà nhỏ hơn a
(ví dụ, giá trị trướca
).
Lưu ý: Một áp phích khác cho biết, 1.0-Double.MIN_NORMAL
. Sai rồi. 1.0-Double.MIN_NORMAL
chính xác bằng 1.0.
Còn khoảng 0.9999999999999999 thì sao? nó có cùng số chữ số, nhưng có số 9 thay vì số 8 ở cuối. Khi tôi 'System.out.println (0.9999999999999999 - 0.9999999999999998)', tôi nhận được: 1.1102230246251565E-16 – Justin
@gangqinlaohu Chữ số cuối cùng không chính xác. Tôi cắt ngắn số mà tôi nhận được từ máy tính IEEE-754 (xem liên kết trong câu trả lời) để lấy số. Chữ số tiếp theo sau 8 cũng là 8, vì vậy nếu bạn áp dụng làm tròn, kết quả sẽ trở thành 0.9999999999999999. – dasblinkenlight
Ồ, vì vậy, 0,9999999999999999 là gần hơn 0,9999999999999998, bởi vì 0,9999999999999998 bị cắt ngắn, do đó, Double gần 1 là 0,9999999999999999. – Justin