Java踩坑——Double类型转String变成了科学计数法怎么解决

现在有一个场景,需要将一个Double类型的字段转换成字符串然后写入文件,不过在某些时候,数字会出现以科学计数法的形式来表示:

1
2
3
4
double scale = 0.0005;
System.out.println(String.valueOf(scale)); // 5.0E-4
System.out.println(scale + ""); // 5.0E-4
System.out.println(scale); // 5.0E-4

如上,在尝试了几种容易想到的方法后,发现均不可行.后来经过搜索和更多次尝试,整理出几种方案:

方案一

使用java.math包的BigDecimal类.效果如下:

1
2
3
double scale = 0.0005;
BigDecimal bigDecimal = new BigDecimal(scale);
System.out.println(bigDecimal); // 0.0005000000000000000104083408558608425664715468883514404296875

由于BigDecimal直接使用不符合我们对小数点后长度的需求,就需要使用String.format()的方式进行转换:

1
2
3
double scale = 0.0005;
BigDecimal bigDecimal = new BigDecimal(scale);
System.out.println(String.format("%.4f", bigDecimal)); // 0.0005

至此问题貌似是解决了,但是依然很不放心.主要原因在于这种方式还是有可能导致误差:毕竟本来我的数字就是标准的0.0005,而BigDecimal因为精度原因需要做截取.

虽然目前看似没有问题,但是如果出现BigDecimal将结果输出成:0.0004999999999999之类的怎么办呢?

这个时候又想到了四舍五入之类的方法,但是总感觉与真正的方法相去越来越远:这么简单的一个转换,不应该搞得这么复杂,于是有了方案二

方案二

这一次是使用java.text包下的DecimalFormat类,具体实现如下:

1
2
3
double scale = 0.0005;
DecimalFormat decimalFormat = new DecimalFormat("#.####");
System.out.println(decimalFormat.format(scale)); // 0.0005

方案三

后来想起来,发现其实上面两种方法都是庸人自扰,属于脑子一下没转过弯来才会干的事…因为实际上问题可以非常简单地解决:

1
2
3
double scale = 0.0005;
String scaleStr = String.format("%.4f", scale);
System.out.println(scaleStr); // 0.0005

好吧,果然这种问题的解决办法一定是非常简单的…