Java使用Math.ceil四舍五入到int

tom*_*tom 92 java math

int total = (int) Math.ceil(157/32);
Run Code Online (Sandbox Code Playgroud)

为什么它仍然返回4?157/32 = 4.90625,我需要围捕,我环顾四周,这似乎是正确的方法.

我想total作为double类型,但得到4.0.

我究竟做错了什么?

mar*_*008 170

你正在做的157/32是将两个整数相互划分,这总是导致一个向下舍入的整数.因此,(int) Math.ceil(...)没有做任何事情.有三种可能的解决方案可以实现您的目标.我建议使用选项1选项2.请不要使用选项0.

选项0

转换a并转换b为double,您可以使用除法并Math.ceil根据需要使用它.但是我强烈反对使用这种方法,因为双重划分可能是不精确的.要阅读更多关于双精度不精确的信息,请参阅此问题.

int n = (int) Math.ceil((double) a / b));
Run Code Online (Sandbox Code Playgroud)

选项1

int n = a / b + ((a % b == 0) ? 0 : 1); 
Run Code Online (Sandbox Code Playgroud)

a / b如果a并且b都是整数,那么你总是使用floor .然后你有一个内联if语句巫婆检查你是否应该ceil而不是floor.所以+1或+0,如果有除法的余数,则需要+1.a % b == 0检查剩余部分.

选项2

此选项非常短,但可能对某些不太直观.我认为这种不那么直观的方法比双重分割和比较方法更快:

int n = (a + b - 1) / b;
Run Code Online (Sandbox Code Playgroud)

为了减少溢出的可能性,您可以使用以下内容.但请注意,它不适用于a = 0b < 1.

int n = (a - 1) / b + 1;
Run Code Online (Sandbox Code Playgroud)

"不太直观的方法"背后的解释

由于在Java(以及大多数其他编程语言)中除以两个整数,因此总是将结果置于底层.所以:

int a, b;
int result = a/b (is the same as floor(a/b) )
Run Code Online (Sandbox Code Playgroud)

但是,我们不希望floor(a/b),但是ceil(a/b),使用维基百科的定义和图:在此输入图像描述

通过这些地板和ceil功能图,您可以看到这种关系.

地板功能 Ceil功能

你可以看到floor(x) <= ceil(x).我们需要floor(x + s) = ceil(x).所以我们需要找到s.如果我们采取1/2 <= s < 1它将是正确的(尝试一些数字,你会看到它,我发现很难证明这一点).而且1/2 <= (b-1) / b < 1,这样

ceil(a/b) = floor(a/b + s)
          = floor(a/b + (b-1)/b)
          = floor( (a+b-1)/b) )
Run Code Online (Sandbox Code Playgroud)

这不是一个真实的证明,但我希望你对此感到满意.如果有人能够更好地解释它,我也会很感激.也许在MathOverflow上问它.

  • 澄清一点:选项 2 的两个子选项的结果并非在所有情况下都相同。a 的值为零将在第一个中提供 0,在第二个中提供 1(这不是大多数应用程序的正确答案)。 (2认同)

Boz*_*zho 59

157/32 int/int,结果是int.

尝试使用double literal - 157/32d,这会int/double产生一个double.

  • @ user1545072:http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.2 (3认同)

rat*_*eak 34

157/32是一个整数除法,因为所有数字文字都是整数,除非另外用后缀指定(对于long d为double l)

在将它转换为double(4.0)然后向上舍入(到4.0)之前,将除法向下舍入(到4)

如果你使用变量,你可以避免这种情况

double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
Run Code Online (Sandbox Code Playgroud)


Pho*_*bus 24

int total = (int) Math.ceil((double)157/32);
Run Code Online (Sandbox Code Playgroud)


I.G*_*ual 8

没有人提到最直观的:

int x = (int) Math.round(Math.ceil((double) 157 / 32));
Run Code Online (Sandbox Code Playgroud)

此解决方案修复了除法的不精确性。