0

お金に関する計算を処理する小さな Java プログラムを作成する必要があります。したがって、精度が必要です。(例: いいえfloat/double変数のみlong)。

残念ながら、使用する必要がある元の値は、変数を「double」としてしか読み取れないメソッドを介してインポートされます。

今、私はそれを次のような方法を使用してにキャストしようとしlongました:

double importedValue = x;
double importedValueConverted = (long) x;

ただし、importedValueConverted を別の「長い」変数で除算しようとすると、次のようになります。

必須: 長い検出: 二重エラー: 精度が失われる可能性があります

何故ですか?

4

6 に答える 6

3
double importedValue = x;
double importedValueConverted = (long) x;

これらの変数は両方とも「double」として宣言されていることに注意してください。これにより、エラーが発生します (言い換え): (実行している操作には a) long(しかし、試したときに a) が見つかりましたdouble

あなたがしたい:

double importedValue = x;
long importedValueConverted = (long) x;
于 2012-09-28T18:11:01.580 に答える
2

すべてのキャスティングビジネスを忘れてください。財務計算を行っている場合は、BigDecimal を直接使用して、いわゆるメソッドによって返された double をラップし、必要に応じて BigDecimal が提供する適切な丸めメカニズムを使用できます。

于 2012-09-28T20:06:30.573 に答える
1

アップデート:

この投稿では、これまで答えられていなかったと思われる追加の質問が提起されintました。これはここで答えられます:longBigDecimal

double や float を使用して通貨 (または正確な計算が必要な場合) を表現しないのはなぜですか?

float と double は、ほとんどの基数 10 の実数を正確に表すことができないためです。

を使用する場合でも、コンストラクターではなくコンストラクターをBigDecimal使用する必要があります。Stringfloat

これはすべて言った、あなたの最善の策は次のとおりです。

  • すべての値をセントに変換し、として保存しますlong(各ドルの金額に 100 を掛けます)
  • セントで操作を行う
  • 最後に100で割ってドルに戻す

これにより、必要な精度が維持されます。明らかに、このソリューションは米ドルを念頭に置いているため、外貨への換算には適切な考慮が必要です。


キャストするのではなく、最も近いlong値に丸めることを検討してください。

double d = 1234.56;
long x = Math.round(d);

doubleなぜ a からaに移動したいのか、本当にお尋ねしますlong。これにより、10 進数値の精度が失われるからです。

ある程度の精度 (たとえば、最大 3 桁) を維持したい場合で、絶対に long でしか作業できない場合は、両方の double に 1,000 を掛けてから、後のすべての操作を同じ係数でスケーリングしてから、それらをスケーリングします。次のように、すべて最後に戻ります。

double starting = 1234.5678;
double worker = starting * 1000;
long roundedWorker = Math.round(worker);

// do other computations here...
// due to earlier scaling, adding 1000 is equivalent to adding 1 to the original
long longResult = roundedWorker + 1000;

double threeDigitPreciseResult = longResult / 1000d;
System.out.println("Adding 1 to original number as a long: " + threeDigitPreciseResult);

アップデート

問題のより良い説明を得た後、あなたが探しているのは によって提供される機能であるように思えますDecimalFormat。以下は、roundToTwoDecimals()それを使用する方法と、それを示すテストケースです。

import java.text.DecimalFormat;

import org.junit.Test;

public class ExampleTest {
  @Test
  public void test() {
    double num1 = 29334.32942032432;
    double num2 = 438.95940;
    double result = num1 / num2;
    System.out.println("Before rounding: " + result);

    double rounded = roundToTwoDecimals(result);
    System.out.println("After rounding: " + rounded);
  }

  public double roundToTwoDecimals(double d) {
    DecimalFormat twoDForm = new DecimalFormat("#.##");
    return Double.valueOf(twoDForm.format(d));
  }

}

どちらが出力されますか:

Before rounding: 66.82697629968585
After rounding: 66.83
于 2012-09-28T18:53:35.350 に答える
0

BigDecimalを見てみましょう。私がそれを使用したとき、それはうまく機能します。ただし、Double はそれほど正確ではないため、Double ctor の使用には注意してください (たとえば、0.1 を正確に格納することはできません)。BigDecimal にString ctorを使用する方が便利な場合があります

于 2012-09-28T18:39:42.290 に答える
0

ダブルからロングにキャストしたい場合は、以下を実行します。

    double importedValue = 8.0;
    long importedValueConverted = (long) 8.0;
    System.out.println(importedValueConverted/(long)8);

出力: 1

double importedValue = x;
double importedValueConverted = (long) x;

double を long にキャストし、キャストされた値を double に再割り当てしようとしていました。long に割り当てる必要があります。

于 2012-09-28T18:14:22.257 に答える
0

xdouble に割り当てようとするよりも long に キャストしています。

それは意味がありません。

ロングが必要な場合は、ロングを使用する必要があります。

long longValue = (long) 4.64;

于 2012-09-28T18:14:34.790 に答える