Java变量转换

时间:2012-09-28 18:07:06

标签: java converter

我需要编写一个小型Java程序来处理涉及金钱的计算。因此它需要具有准确性。 (例如:没有float / double个变量,只有long)。

不幸的是,我需要使用的原始值是通过一个只能将变量读取为“double”的方法导入的。

现在,我尝试使用类似于:

的方法将其转换为long
double importedValue = x;
double importedValueConverted = (long) x;

然而,当我尝试将importedValueConverted除以另一个“long”变量时,我得到:

  

要求:长   发现:双倍   错误:可能损失精度

为什么?

6 个答案:

答案 0 :(得分:3)

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

请注意,这两个变量都声明为“double”。这会导致您的错误(释义):(您正在进行的操作需要a long(但在尝试时发现了)double

你想:

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

答案 1 :(得分:2)

忘记所有的铸造业务。如果您正在使用财务计算,您可以直接使用BigDecimal来包装您所谓的方法返回的双精度数,并使用BigDecimal提供的适合您需要的舍入机制。

答案 2 :(得分:1)

<强>更新

这篇文章提出了一个我认为没有回答过的问题 - 为什么要使用int,或者更好,longBigDecimal进行货币计算。这在这里得到解答:

Why not to use double or float to represent currency (or where any exact calculations are needed)?

  

因为浮点数和双打数不能准确地代表大多数基数10   实数。

即使使用BigDecimal,也必须使用String构造函数而不是float构造函数。

这一切都说,你最好的选择是:

  • 将所有值转换为美分并存储为long(将每个美元金额乘以100)
  • 以分数进行操作
  • 最后除以100转换回美元

这将保持所需的准确性。显然这个解决方案考虑到了美元,任何对外币的转换都需要适当的考虑。


考虑舍入到最接近的long值而不是强制转换:

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

我真的问你为什么要从double转到long,因为这会让你失去小数值的精确度。

如果你想保持一定的精确度(比方说多达3位数),你绝对只能用长这样做,你可以将两个双倍乘以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

答案 3 :(得分: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。你应该把它分配给很长时间。

答案 4 :(得分:0)

您要将x投射到比尝试将其分配给双精灵更长的时间。

这没有用。

如果你想长,你应该使用很长的。

long longValue = (long) 4.64;

答案 5 :(得分:0)

为什么不看BigDecimal。我使用它时效果很好。小心使用Double ctor虽然Double不是那么精确(例如它不能精确地存储0.1)。将String ctor用于BigDecimal

可能更有用