web-dev-qa-db-ja.com

Java Math.ceilを使用してintに切り上げる

int total = (int) Math.ceil(157/32);

まだ4を返すのはなぜですか? 157/32 = 4.90625、切り上げる必要があります。見回しましたが、これが正しい方法のようです。

totalタイプとしてdoubleを試しましたが、4.0を取得しました。

私は何を間違えていますか?

89
tom

2つの整数を互いに分割する157/32を実行しているため、常に切り捨てられた整数になります。したがって、(int) Math.ceil(...)は何もしていません。あなたが望むものを達成するための3つの可能な解決策があります。 Irecommendoption 1またはオプション2。してくださいNOTuseoption 0.

オプション0

abをdoubleに変換すると、除算とMath.ceilを使用したいときに使用できます。ただし、二重分割は不正確になる可能性があるため、このアプローチの使用は強くお勧めしません。 doubleの不正確さについて詳しくは、 この質問 を参照してください。

int n = (int) Math.ceil((double) a / b));

オプション1

int n = a / b + ((a % b == 0) ? 0 : 1); 

abが両方とも整数である場合、常にフロアでa / bを実行します。次に、インラインifステートメントの魔女が、フロアの代わりに天井を置くべきかどうかをチェックします。 +1または+0です。除算に余りがある場合は、+ 1が必要です。 a % b == 0は残りをチェックします。

オプション2

このオプションは非常に短いですが、いくつかの直感的でない可能性があります。この直感的ではないアプローチは、二重除算および比較アプローチよりも速いと思います。

int n = (a + b - 1) / b;

オーバーフローの可能性を減らすには、次を使用できます。ただし、a = 0およびb < 1では機能しないことに注意してください。

int n = (a - 1) / b + 1;

「直感的でないアプローチ」の背後にある説明

Java(および他のほとんどのプログラミング言語)で2つの整数を除算すると、常に結果がフロアリングされます。そう:

int a, b;
int result = a/b (is the same as floor(a/b) )

しかし、floor(a/b)ではなくceil(a/b)を必要とせず、 Wikipedia の定義とプロットを使用します。 enter image description here

床と天井関数のこれらのプロットを使用すると、関係を確認できます。

Floor functionCeil function

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) )

これは本当の証拠ではありませんが、皆さんが満足していることを願っています。誰かがそれをもっとうまく説明できれば、私も感謝します。多分 MathOverflow で聞いてください。

166
martijnn2008

157/32はint/intであり、intになります。

ダブルリテラル-157/32dを使用してみてください。これはint/doubleで、結果はdoubleになります。

59
Bozho

157/32は整数の除算です。数値リテラルはすべて、特に接尾辞(_の場合はd、長い場合はl)を指定しない限り整数であるためです。

除算は、倍数(4.0)に変換される前に切り下げられ(4に)、その後、切り上げられます(4.0に)

変数を使用すると、それを回避できます

double a1=157;
double a2=32;
int total = (int) Math.ceil(a1/a2);
34
ratchet freak
int total = (int) Math.ceil((double)157/32);
24
Phoebus

Javaでは、.0を追加すると二重になります...

int total = (int) Math.ceil(157.0 / 32.0);
3
Scott Higgins

2つの整数を除算する場合、たとえば

int c = (int) a / (int) b;

結果はintになり、その値はabで除算し、ゼロに丸められます。結果はすでに丸められているため、ceil()は何もしません。この丸めは、負の無限大に丸めるfloor()と同じではないことに注意してください。したがって、3/21と等しい(およびfloor(1.5)1.0と等しいが、(-3)/2-1と等しい(ただしfloor(-1.5)-2.0と等しい)。

これは、a/bが常にfloor(a / (double) b)と同じである場合、a/bceil()-( (-a) / b)として実装できるため、重要です。

からceil(a/b)を取得する提案

int n = (a + b - 1) / b;a / b + (b - 1) / b、または(a - 1) / b + 1と同等

a/bが整数の場合を除き、ceil(a/b)は常にfloor(a/b)よりも1大きいため、機能します。したがって、a/bが整数でない限り、次の整数に(または過去に)バンプする必要があります。 1 - 1 / bを追加すると、これが実行されます。整数の場合、次の整数までプッシュすることはできません。他のすべてについては、そうなります。

うわぁ。うまくいけば、それは理にかなっています。私はそれを説明するより数学的にエレガントな方法があると確信しています。

3
jorgenman
int total = (int) Math.ceil( (double)157/ (double) 32);
2
stones333

質問については、以下の解決策を確認してください。

int total = (int) Math.ceil(157/32);

ここでNumeratorに1.0を掛けると、答えが得られます。

int total = (int) Math.ceil(157*1.0/32);
1
Un known

最も直観的なものは誰も言及していません。

int x = (int) Math.round(Math.ceil((double) 157 / 32));

このソリューションはdouble除算の不正確さを修正します。

1
I.G. Pascual

また、数値を整数から実数に変換するには、ドットを追加できます。

int total = (int) Math.ceil(157/32.);

また、(157/32。)の結果も実際になります。 ;)

1
Vitaliy Borisok

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+1r₁に置き換えることができます:

ceil(q*k+r+1, k) == q+1  , where 0 ≤ r ≤ k-1


次に、最初の式をq取得の3番目に代入します

ceil(q*k+r+1, k) == floor(q*k+r, k) + 1  , where 0 ≤ r ≤ k-1

最後に、任意の整数yを指定します。ここで、いくつかのqkry = q*k+r+1は、

ceil(y, k) == floor(y-1, k) + 1

これで完了です。お役に立てれば。

0
ShellayLee

Doubleを使用してキャストする

Math.ceil((double)value)など

Math.ceil((double)value1/(double)value2);
0
Bhupinder

Double値を切り上げるには2つの方法があります。

  1. Math.ceil
  2. Math.floor

回答4.90625を4にしたい場合はMath.floorを使用し、回答4.90625を5にしたい場合はMath.ceilを使用できます

次のコードを参照できます。

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);

    }

}
0
Deepak Kumbhar