int total = (int) Math.ceil(157/32);
为什么它仍然会返回4? 157/32 = 4.90625
,我需要围捕,我环顾四周,这似乎是正确的方法。
我尝试将total
作为double
类型,但获得了4.0。
我做错了什么?
答案 0 :(得分:154)
你正在做157/32
,它将两个整数相互划分,这总是导致一个向下舍入的整数。因此(int) Math.ceil(...)
没有做任何事情。有三种可能的解决方案可以实现您的目标。我推荐使用选项1 或选项2 。请不使用选项0 。
将a
和b
转换为double,您可以根据需要使用除法和Math.ceil
。但是我强烈反对使用这种方法,因为双重划分可能是不精确的。要阅读有关双精度不精确的更多信息,请参阅this question。
int n = (int) Math.ceil((double) a / b));
int n = a / b + ((a % b == 0) ? 0 : 1);
如果a / b
和a
都是整数,则b
始终为a % b == 0
。然后你有一个内联if语句巫婆检查你是否应该ceil而不是floor。所以+1或+0,如果有除法的余数,则需要+1。 int n = (a + b - 1) / b;
检查剩余部分。
此选项非常短,但可能对某些不太直观。我认为这种不那么直观的方法比双重分割和比较方法更快:
a = 0
为了减少溢出的可能性,您可以使用以下内容。但请注意,它不适用于b < 1
和int n = (a - 1) / b + 1;
。
int a, b;
int result = a/b (is the same as floor(a/b) )
由于在Java(以及大多数其他编程语言)中分割两个整数,因此总是将结果置于底层。所以:
floor(a/b)
但我们不希望ceil(a/b)
,而是floor(x) <= ceil(x)
,并使用Wikipedia中的定义和图表:
通过这些地板和ceil功能图可以看出这种关系。
您可以看到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) )
,所以
{{1}}
这不是一个真实的证明,但我希望你对它感到满意。如果有人能够更好地解释它,我也会很感激。也许在MathOverflow上询问。
答案 1 :(得分:57)
157/32为int/int
,结果为int
。
尝试使用双{ - 1}} 157/32d
,这会产生int/double
。
答案 2 :(得分:34)
157/32
是一个整数除法,因为所有数字文字都是整数,除非另外指定后缀(d
用于加倍l
)
除非转换为双精度(4.0),然后向上舍入(至4.0)
,将除法向下舍入(至4)如果您使用变量,则可以避免
double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
答案 3 :(得分:24)
int total = (int) Math.ceil((double)157/32);
答案 4 :(得分:3)
在Java中添加.0会使它成为双倍......
int total = (int) Math.ceil(157.0 / 32.0);
答案 5 :(得分:3)
分割两个整数时,例如,
int c = (int) a / (int) b;
结果为int
,其值为a
除以b
,舍入为零。由于结果已经四舍五入,ceil()
没有做任何事情。请注意,此舍入与floor()
不同,后者向负无穷大舍入。因此,3/2
等于1
(和floor(1.5)
等于1.0
,但(-3)/2
等于-1
(但floor(-1.5)
等于{{1} }})。
这很重要,因为如果-2.0
始终与a/b
相同,那么您只需将floor(a / (double) b)
ceil()
实现为a/b
。
从
获取-( (-a) / b)
的建议
ceil(a/b)
,相当于int n = (a + b - 1) / b;
或a / b + (b - 1) / b
有效,因为(a - 1) / b + 1
总是大于ceil(a/b)
,除非floor(a/b)
是整数。因此,除非a/b
是整数,否则您希望将其提升到(或超过)下一个整数。添加a/b
即可。对于整数而言,它不会将它们推向下一个整数。对于其他一切,它会。
让人惊讶。希望这是有道理的。我确信这是一种更加数学上优雅的方式来解释它。
答案 6 :(得分:2)
int total = (int) Math.ceil( (double)157/ (double) 32);
答案 7 :(得分:1)
另外,要将数字从整数转换为实数,您可以添加一个点:
int total = (int) Math.ceil(157/32.);
(157/32。)的结果也是真实的。 ;)
答案 8 :(得分:1)
检查以下解决方案以获取您的问题:
int total = (int) Math.ceil(157/32);
在这里你应该将Numerator与1.0相乘,然后它会给出你的答案。
int total = (int) Math.ceil(157*1.0/32);
答案 9 :(得分:1)
没人提到最直观的:
int x = (int) Math.round(Math.ceil((double) 157 / 32));
此解决方案修复了 double 除法不精确。
答案 10 :(得分:1)
您可以通过两种方法对双倍值进行舍入。
如果您希望答案4.90625为4,那么您应该使用Math.floor,如果您希望答案4.90625为5,那么您可以使用Math.ceil
您可以参考以下代码。
<meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key" /> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
答案 11 :(得分:0)
使用double来施放
Math.ceil((double)value)
或类似
Math.ceil((double)value1/(double)value2);
答案 12 :(得分:0)
默认情况下,Java仅提供楼层划分/
。但我们可以在楼层方面写上限。我们来看看:
任何整数y
都可以使用y == q*k+r
形式编写。根据地板划分的定义(此处为floor
),它围绕r
,
floor(q*k+r, k) == q , where 0 ≤ r ≤ k-1
和天花板分区(此处为ceil
),它围绕r₁
,
ceil(q*k+r₁, k) == q+1 , where 1 ≤ r₁ ≤ k
我们可以将r+1
替换为r₁
:
ceil(q*k+r+1, k) == q+1 , where 0 ≤ r ≤ k-1
然后我们将第一个等式代入q
得到
ceil(q*k+r+1, k) == floor(q*k+r, k) + 1 , where 0 ≤ r ≤ k-1
最后,给定y
y = q*k+r+1
q
,k
,r
的任何整数ceil(y, k) == floor(y-1, k) + 1
,我们有
{{1}}
我们完成了。希望这会有所帮助。
答案 13 :(得分:0)
我知道这是一个老问题,但是我认为我们有一个更好的方法,该方法使用BigDecimal来避免精度损失。顺便说一句,使用此解决方案,我们可以使用多种舍入和缩放策略。
final var dividend = BigDecimal.valueOf(157);
final var divisor = BigDecimal.valueOf(32);
final var result = dividend.divide(divisor, RoundingMode.CEILING).intValue();
答案 14 :(得分:-3)
int total = (157-1)/32 + 1
或更一般
(a-1)/b +1