Câu trả lời:
Bạn đang làm 157/32
đó là chia hai số nguyên với nhau, luôn dẫn đến một số nguyên làm tròn xuống. Vì vậy, (int) Math.ceil(...)
không làm bất cứ điều gì. Có ba giải pháp khả thi để đạt được điều bạn muốn. Tôi khuyên bạn nên sử dụng tùy chọn 1 hoặc tùy chọn 2 . Vui lòng KHÔNG sử dụng tùy chọn 0 .
## Tùy chọn 0
Chuyển đổi a
và b
thành một đôi, và bạn có thể sử dụng phép chia và Math.ceil
như bạn muốn nó hoạt động. Tuy nhiên, tôi thực sự không khuyến khích việc sử dụng phương pháp này, vì phép chia đôi có thể không chính xác. Để đọc thêm về không bao quy đầu của đôi, hãy xem câu hỏi này .
int n = (int) Math.ceil((double) a / b));
##Lựa chọn 1
int n = a / b + ((a % b == 0) ? 0 : 1);
Bạn làm a / b
với luôn sàn nếu a
và b
cả hai đều là số nguyên. Sau đó, bạn có một phù thủy câu lệnh if nội tuyến kiểm tra xem bạn có nên dừng thay vì sàn hay không. Vì vậy, +1 hoặc +0, nếu có phần dư với phép chia, bạn cần +1. a % b == 0
kiểm tra phần còn lại.
##Lựa chọn 2
Tùy chọn này rất ngắn, nhưng có thể đối với một số người ít trực quan hơn. Tôi nghĩ rằng cách tiếp cận ít trực quan hơn này sẽ nhanh hơn so với cách tiếp cận chia đôi và so sánh:
Xin lưu ý rằng cách này không hoạt động cho b < 0
.
int n = (a + b - 1) / b;
Để giảm nguy cơ tràn, bạn có thể sử dụng các cách sau. Tuy nhiên, xin lưu ý rằng nó không hoạt động cho a = 0
và b < 1
.
int n = (a - 1) / b + 1;
## Giải thích đằng sau "cách tiếp cận ít trực quan hơn"
Vì phép chia hai số nguyên trong Java (và hầu hết các ngôn ngữ lập trình khác) sẽ luôn dẫn đến kết quả giống nhau. Vì thế:
int a, b;
int result = a/b (is the same as floor(a/b) )
Nhưng chúng tôi không muốn floor(a/b)
, nhưng ceil(a/b)
và sử dụng các định nghĩa và âm mưu từ Wikipedia :
Với những mảnh đất này của tầng và chức năng, bạn có thể thấy mối quan hệ.
Bạn có thể thấy điều đó floor(x) <= ceil(x)
. Chúng tôi cần floor(x + s) = ceil(x)
. Vì vậy, chúng ta cần phải tìm s
. Nếu chúng ta chấp nhận 1/2 <= s < 1
nó sẽ vừa phải (hãy thử một số con số và bạn sẽ thấy nó đúng, bản thân tôi thấy rất khó để chứng minh điều này). Và 1/2 <= (b-1) / b < 1
, vì vậy
ceil(a/b) = floor(a/b + s)
= floor(a/b + (b-1)/b)
= floor( (a+b-1)/b) )
Đây không phải là một bằng chứng thực tế, nhưng tôi hy vọng bạn hài lòng với nó. Nếu ai đó có thể giải thích nó tốt hơn, tôi cũng sẽ đánh giá cao nó. Có thể hỏi nó trên MathOverflow .
157/32 là int/int
, dẫn đến một int
.
Hãy thử sử dụng chữ kép - 157/32d
, nghĩa là int/double
, kết quả là a double
.
157/32
là một phép chia số nguyên vì tất cả các chữ số đều là số nguyên trừ khi được chỉ định khác bằng một hậu tố ( d
đối với kép l
dài)
phép chia được làm tròn xuống (thành 4) trước khi chuyển thành kép (4,0), sau đó được làm tròn lên (thành 4,0)
nếu bạn sử dụng một biến, bạn có thể tránh điều đó
double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
Không ai đã đề cập đến trực quan nhất:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
Giải pháp này khắc phục sự không chính xác của phép chia đôi .
Trong Java, thêm một .0 sẽ làm cho nó trở thành ...
int total = (int) Math.ceil(157.0 / 32.0);
Khi chia hai số nguyên, ví dụ:
int c = (int) a / (int) b;
kết quả là một int
, giá trị của nó được a
chia cho b
, làm tròn về 0. Bởi vì kết quả đã được làm tròn, ceil()
không làm bất cứ điều gì. Lưu ý rằng việc làm tròn này không giống như làm floor()
tròn về phía âm vô cực. Vì vậy, 3/2
bằng 1
(và floor(1.5)
bằng 1.0
, nhưng (-3)/2
bằng -1
(nhưng floor(-1.5)
bằng -2.0
).
Đây là quan trọng bởi vì nếu a/b
lúc nào cũng giống như floor(a / (double) b)
, sau đó bạn chỉ có thể thực hiện ceil()
các a/b
như -( (-a) / b)
.
Đề xuất nhận được ceil(a/b)
từ
int n = (a + b - 1) / b;
, tương đương với a / b + (b - 1) / b
, hoặc(a - 1) / b + 1
hoạt động bởi vì ceil(a/b)
luôn luôn lớn hơn floor(a/b)
, ngoại trừ khi a/b
là một số nguyên. Vì vậy, bạn muốn chuyển nó sang (hoặc qua) số nguyên tiếp theo, trừ khi a/b
là một số nguyên. Thêm1 - 1 / b
sẽ làm điều này. Đối với số nguyên, nó sẽ không hoàn toàn đẩy chúng lên số nguyên tiếp theo. Đối với mọi thứ khác, nó sẽ.
Rất tiếc. Hy vọng rằng điều đó có ý nghĩa. Tôi chắc chắn rằng có một cách giải thích toán học thanh lịch hơn.
Ngoài ra, để chuyển đổi một số từ số nguyên sang số thực, bạn có thể thêm dấu chấm:
int total = (int) Math.ceil(157/32.);
Và kết quả của (157/32.) Cũng sẽ là thực. ;)
Kiểm tra giải pháp bên dưới cho câu hỏi của bạn:
int total = (int) Math.ceil(157/32);
Ở đây bạn nên nhân Numerator với 1,0, sau đó nó sẽ cho câu trả lời của bạn.
int total = (int) Math.ceil(157*1.0/32);
Java chỉ cung cấp phân chia tầng /
theo mặc định. Nhưng chúng ta có thể viết trần về mặt sàn . Hãy xem nào:
Bất kỳ số nguyên nào y
cũng có thể được viết với biểu mẫu y == q*k+r
. Theo định nghĩa của phân chia tầng (tại đây floor
) làm tròn r
,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
và phân chia trần (tại đây ceil
) làm tròn lên r₁
,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
nơi chúng tôi có thể thay thế r+1
cho r₁
:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
Sau đó, chúng tôi thay thế phương trình đầu tiên thành phương trình thứ ba để q
nhận được
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
Cuối cùng, với bất kỳ số nguyên y
nơi y = q*k+r+1
đối với một số q
, k
, r
, chúng tôi có
ceil(y, k) == floor(y-1, k) + 1
Và chúng tôi đã hoàn thành. Hi vọng điêu nay co ich.
ceil
được định nghĩa như vậy từ định nghĩa trực quan, cụ thể là khi chúng ta lấy dấu của một số nguyên, tức là r1 = k. Vì các trường hợp cạnh là điều khó khăn về điều này, tôi nghĩ rằng nó cần phải được viết rõ hơn một chút.
Có hai phương pháp mà bạn có thể làm tròn giá trị nhân đôi của mình.
Nếu bạn muốn câu trả lời của mình là 4.90625 là 4 thì bạn nên sử dụng Math.floor và nếu bạn muốn câu trả lời của mình là 4.90625 là 5 thì bạn có thể sử dụng Math.ceil
Bạn có thể tham khảo mã sau đây cho điều đó.
public class TestClass {
public static void main(String[] args) {
int floorValue = (int) Math.floor((double)157 / 32);
int ceilValue = (int) Math.ceil((double)157 / 32);
System.out.println("Floor: "+floorValue);
System.out.println("Ceil: "+ceilValue);
}
}
int total = (157-1)/32 + 1
hoặc tổng quát hơn
(a-1)/b +1