web-dev-qa-db-ja.com

整数除算:どうのように倍精度を作り出しますか?

このコードブロックの場合:

int num = 5;
int denom = 7;
double d = num / denom;

dの値は0.0です。それはキャストによって働くことを強いられることができます:

double d = ((double) num) / denom;

しかし、正しいdouble結果を得るための別の方法はありますか?私はプリミティブをキャストするのは嫌いです。

219
walnutmon
double num = 5;

それはキャストを避けます。しかし、キャスト変換は明確に定義されていることがわかります。推測する必要はありません。 JLS を確認するだけです。 intからdoubleへの変換は拡大変換です。 From §5.1.2

プリミティブ変換を広げても、数値全体の大きさに関する情報が失われることはありません。

[...]

Int型またはlong型の値からfloat型への変換、またはlong型の値からdouble型への変換により、精度が低下する可能性があります。つまり、結果の値の最下位ビットの一部が失われる可能性があります。この場合、結果の浮動小数点値は、IEEE 754の最近傍丸めモード を使用して、整数値を正しく丸めたものになります(§4.2.4)

5は正確にdoubleとして表現できます。

144

プリミティブのキャストの何が問題になっていますか

何らかの理由でキャストしたくない場合は、

double d = num * 1.0 / denom;
93
Paul Tomblin

私はプリミティブをキャストするのは嫌いです。

なぜあなたはプリミティブをキャストすることを非合理的な恐れがあるのですか? intdoubleにキャストしても悪いことは何も起こりません。それがどのように機能するのかわからない場合は、 Java言語仕様 で調べてください。 intdoubleにキャストすることは、 拡大プリミティブ変換 です。

分子の代わりに分母をキャストすることで、余分な括弧の組を取り除くことができます。

double d = num / (double) denom;
65
Jesper

1つの型を変更すると、数式が変更されたときに覚えておく必要がある変数が再びダブルに隠れるため、この変数が計算の一部にならなくなると、結果はめちゃくちゃになります。計算内でキャストする習慣を作り、その横にコメントを追加します。

double d = 5 / (double) 20; //cast to double, to do floating point calculations

結果をキャストしてもうまくいかないことに注意してください。

double d = (double)(5 / 20); //produces 0.0
25
alianos-

浮動小数点Mathで操作を強制的に実行するには、整数の1つまたは両方の整数をfloatにキャストします。そうでなければ整数Mathが常に好まれます。そう:

1. double d = (double)5 / 20;
2. double v = (double)5 / (double) 20;
3. double v = 5 / (double) 20;

結果をキャストしても実行されないことに注意してください。優先順位に従って最初の分割が行われるからです。

double d = (double)(5 / 20); //produces 0.0

私はあなたが考えているそのようなものとしてキャストに問題があるとは思わない。

15
Nikhil Kumar

タイプキャスティングが唯一の方法


整数の除算からdoubleを生成する - キャスティング なしでは他に方法はありません(明示的に行わないかもしれませんが起こるでしょう)。

さて、正確なdouble値を得るために試みることができるいくつかの方法があります(ここでnumdenomint型であり、そしてもちろんとキャスト) -

  1. 明示的キャストを使用すると、

    • double d = (double) num / denom;
    • double d = ((double) num) / denom;
    • double d = num / (double) denom;
    • double d = (double) num / (double) denom;

double d = (double) (num / denom);ではなく

  1. 暗黙的キャストを使って:

    • double d = num * 1.0 / denom;
    • double d = num / 1d / denom;
    • double d = ( num + 0.0 ) / denom;
    • double d = num; d /= denom;

double d = num / denom * 1.0;ではなく
double d = 0.0 + ( num / denom );ではなく

8
Minhas Kamal

以下のように使用してください。

double step = 1d / 5;

(1dはdoubleへのキャストです)

2
ungalcrys

操作をラップすることを検討するかもしれません。例えば:

class Utils
{
    public static double divide(int num, int denom) {
        return ((double) num) / denom;
    }
}

これにより、キャストが自分の望むとおりに機能しているかどうかを(一度だけ)調べることができます。このメソッドは、テストを受けて、必要なことを確実に実行できるようにすることもできます。それが正しい結果をもたらす限り、それはあなたが分割を引き起こすためにあなたがどのトリックを使うか(あなたはここでの答えのうちのどれでも使うことができる)も問題ではありません。 2つの整数を分割する必要がある場所ならどこでも、Utils::divideを呼び出すだけで、正しいことができると信頼できます。

これを使うだけです。

int fxd=1;
double percent= (double)(fxd*40)/100;
0
Mabood Ahmad

これを行うための最良の方法は

int i = 3;
Double d = i * 1.0;

d is 3.0 now.
0
Alp Altunel