Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/244.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-避免字符串中的指数转换为双精度转换_Android_String_Double_Type Conversion - Fatal编程技术网

Android-避免字符串中的指数转换为双精度转换

Android-避免字符串中的指数转换为双精度转换,android,string,double,type-conversion,Android,String,Double,Type Conversion,我试图从edittext中获取值并将其存储为字符串。然后它转换为双精度。转换最多7个字符时功能正常,但如果我尝试添加7个以上的字符,结果是1.23456789E8。这是我的密码 String value = txtData.txtSearch.getText().toString(); // value = "987654321.45" double amount1 = Double.parseDouble(value); // amount1 = 9.8765432145E8 double

我试图从edittext中获取值并将其存储为字符串。然后它转换为双精度。转换最多7个字符时功能正常,但如果我尝试添加7个以上的字符,结果是1.23456789E8。这是我的密码

String value = txtData.txtSearch.getText().toString();
// value = "987654321.45"

double amount1 = Double.parseDouble(value);
// amount1 = 9.8765432145E8

double amount2 = 0.05;

double result = (amount1 * amount2) / 100;
// result = 4.3827160725E14
经过计算,我得到了4.3827160725E14,这是不正确的答案是493827.16


如何在不损失精度的情况下获得正确的值?

以下代码给出了您的预期结果:

public class DoubleTest {
 public static void main(String[] args) {
      double amount1 = Double.parseDouble("987654321.45");
      double amount2 = 0.05;
      double result = (amount1 * amount2) / 100;
      System.out.println(result);
 }
}
那么,您确定您从
txtData.txtSearch.getText().toString()获得了您认为来自的值吗

顺便说一句,如果你真的对任意精度感兴趣(例如在处理金钱时),请使用BigDecimal。

试试以下方法:

double result = (amount1 * amount2) / 100.0;
string resultInMyFormat =  new DecimalFormat("#.#").format(result);

我解决了。我使用BigDecimal而不是double现在我的代码是

String value = txtData.txtSearch.getText().toString();
// value = "987654321.45"

BigDecimal amount1 = new BigDecimal(value);
// amount1 = "987654321.45"

BigDecimal amount2 = new BigDecimal(0.05);

BigDecimal result = (amount1.multiply(amount2)).divide(new BigDecimal(100));
result = result.setScale(2, RoundingMode.FLOOR);
// result = 493827.16
如何避免字符串中的指数转换为双精度转换

我想我们都没有抓住要点

以下是您的示例:

// value = "987654321.45"

double amount1 = Double.parseDouble(value);
// amount1 = 9.8765432145E8
大概,评论中的内容是打印出来的;e、 g.使用调试器或调用
println

那么为什么你会看到指数/科学符号呢

这并不是因为字符串被解析为双精度的方式。实际上,当
double
转换回字符串以打印它时,就会发生这种情况。例如:

$ cat Test.java
import java.text.DecimalFormat;

public class Test {
    public static void main(String[] args) {
        String value = "987654321.45";
        double amount = Double.parseDouble(value);
        System.out.println(amount);
        DecimalFormat format = new DecimalFormat("0.########");
        System.out.println(format.format(amount));
    }
}
$ java Test
9.8765432145E8
987654321.45
看到了吗?我从“987654321.45”开始,将其转换为
双精度
。然后用两种不同的方式打印。对于相同的
double
值,得到了两种不同的字符串表示形式


那么为什么
println(double)
会这样打印数字呢

  • System.out
    是一个
    PrintStream
  • println(double)
    相当于
    print(double)
    后跟
    println()
  • print(double)
    使用
    String.valueOf(double)
  • valueOf(double)
    返回与
    double.toString(double)
  • toString(double)
    指定在数字大小小于10-3或大于或等于107时使用科学记数法
  • 这些都在各自的Javadoc中指定。最突出的是for
    toString(double)


    如果你不相信我,你可以检查Java语言规范和IEE754标准的浮点表示法;看

    如果愿意,甚至可以使用
    Double.Double或awlongbits(Double)
    检查
    Double
    值的位表示


    最后

    经过计算,我得到了不正确的
    4.3827160725E14
    ,正确答案是
    493827.16

    当我重复计算时,我得到了答案
    493827.1607250001
    。。。使用
    System.out.println(双精度)
    。(请注意,没有科学符号……因为数字小于107。)

    计算的准确答案(1987654321.45*0.05)/100 493827.160725。精确答案与Java给出的答案之间的差异是由计算机浮点舍入误差造成的。之所以会出现这种情况,是因为IEE 754表示法实际上是具有二进制尾数和二进制指数的二进制表示法,而且尾数具有固定数量的精度二进制数字

    这种舍入误差是使用IEE 754表示法进行计算时固有的。如果你想减轻它,你可以用
    BigDecimal
    来表示你的数字。但您应该知道,即使是
    BigDecimal
    也不精确:

    • 不能使用
      BigDecimal
      精确表示Pi或任何其他无理数

    • 许多有理数没有一个精确的表示形式,即
      BigDecimal
      ;e、 g.1.0/3.0的值


    因此,您(理论上)仍然需要关注
    BigDecimal

    尝试long而不是double的舍入错误