我想在没有指数形式的Java中打印double值.
double dexp = 12345678;
System.out.println("dexp: "+dexp);
Run Code Online (Sandbox Code Playgroud)
它显示了这个E符号:1.2345678E7.
我希望它像这样打印: 12345678
防止这种情况的最佳方法是什么?
Eri*_*ski 221
将双精度数转换为正常数的五种不同方法:
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class Runner {
public static void main(String[] args) {
double myvalue = 0.00000021d;
//Option 1 Print bare double.
System.out.println(myvalue);
//Option2, use decimalFormat.
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(8);
System.out.println(df.format(myvalue));
//Option 3, use printf.
System.out.printf("%.9f", myvalue);
System.out.println();
//Option 4, convert toBigDecimal and ask for toPlainString().
System.out.print(new BigDecimal(myvalue).toPlainString());
System.out.println();
//Option 5, String.format
System.out.println(String.format("%.12f", myvalue));
}
}
Run Code Online (Sandbox Code Playgroud)
该程序打印:
2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000
Run Code Online (Sandbox Code Playgroud)
哪些都是相同的价值.
Protip:如果你对为什么那些随机数字出现在双值的某个阈值之外感到困惑,这个视频解释了:computerphile为什么0.1+ 0.2相等0.30000000000001?
http://youtube.com/watch?v=PZRI1IfStY0
NPE*_*NPE 108
你可以使用printf()同%f:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
Run Code Online (Sandbox Code Playgroud)
这将打印dexp: 12345678.000000.如果您不想要小数部分,请使用
System.out.printf("dexp: %.0f\n", dexp);
Run Code Online (Sandbox Code Playgroud)
这使用文档中说明的格式说明符语言.
toString()原始代码中使用的默认格式在此处拼写出来.
JBE*_*JBE 89
简而言之:
如果你想摆脱尾随零和Locale问题,那么你应该使用:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS
System.out.println(df.format(myValue)); // Output: 0.00000021
Run Code Online (Sandbox Code Playgroud)
说明:
为什么其他答案不适合我:
Double.toString()或者System.out.println或FloatingDecimal.toJavaFormatString使用科学记数法如果双小于10 ^ -3,或者大于或等于10 ^ 7通过使用%f,默认的小数精度为6,否则您可以对其进行硬编码,但如果您有更少的小数,则会导致额外的零.例:
double myValue = 0.00000021d;
String.format("%.12f", myvalue); // Output: 0.000000210000
Run Code Online (Sandbox Code Playgroud)通过使用setMaximumFractionDigits(0);或%.0f删除任何小数精度,这对于整数/长整数,但不是双精度:
double myValue = 0.00000021d;
System.out.println(String.format("%.0f", myvalue)); // Output: 0
DecimalFormat df = new DecimalFormat("0");
System.out.println(df.format(myValue)); // Output: 0
Run Code Online (Sandbox Code Playgroud)通过使用DecimalFormat,您是本地依赖的.在法语区域设置中,小数点分隔符是逗号,而不是点:
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0");
df.setMaximumFractionDigits(340);
System.out.println(df.format(myvalue)); // Output: 0,00000021
Run Code Online (Sandbox Code Playgroud)
使用ENGLISH语言环境可确保在程序运行的任何位置获得小数点分隔符.
为什么使用340 setMaximumFractionDigits呢?
两个原因:
setMaximumFractionDigits接受一个整数,但其实现的最大允许位数DecimalFormat.DOUBLE_FRACTION_DIGITS等于340Double.MIN_VALUE = 4.9E-324 所以340位数字你肯定不会绕过你的双倍而失去精确度.Obl*_*obl 27
你可以尝试一下DecimalFormat.使用此类,您可以非常灵活地解析数字.
您可以准确设置要使用的模式.
以你的情况为例:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
Run Code Online (Sandbox Code Playgroud)
Man*_*uel 16
我有另一个涉及BigDecimal的toPlainString()的解决方案,但这次使用的是字符串构造函数,这在javadoc中是推荐的:
此构造函数与Float.toString和Double.toString返回的值兼容.这通常是将float或double转换为BigDecimal的首选方法,因为它不会受到BigDecimal(double)构造函数的不可预测性的影响.
它看起来像最短的形式:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
Run Code Online (Sandbox Code Playgroud)
在Java 8之前,对于任何零值双打,这会产生"0.0",因此您需要添加:
if (myDouble.doubleValue() == 0)
return "0";
Run Code Online (Sandbox Code Playgroud)
必须额外检查NaN和无限值.
所有这些考虑的最终结果:
public static String doubleToString(Double d) {
if (d == null)
return null;
if (d.isNaN() || d.isInfinite())
return d.toString();
// Pre Java 8, a value of 0 would yield "0.0" below
if (d.doubleValue() == 0)
return "0";
return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}
Run Code Online (Sandbox Code Playgroud)
这也可以复制/粘贴,以便与Float很好地配合使用.
只要您的号码是一个整数,这将有效:
double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);
Run Code Online (Sandbox Code Playgroud)
如果double变量在小数点后具有精度,则会截断它.
Java/Kotlin 编译器将任何大于 9999999(大于或等于 1000 万)的值转换为科学记数法,即。Epsilon 符号。
例如:12345678 转换为 1.2345678E7
使用此代码可避免自动转换为科学记数法:
fun setTotalSalesValue(String total) {
var valueWithoutEpsilon = total.toBigDecimal()
/* Set the converted value to your android text view using setText() function */
salesTextView.setText( valueWithoutEpsilon.toPlainString() )
}
Run Code Online (Sandbox Code Playgroud)
我需要将一些双精度值转换为货币值,发现大多数解决方案都可以,但不适合我。
这DecimalFormat最终适合我,所以这就是我所做的:
public String foo(double value) //Got here 6.743240136E7 or something..
{
DecimalFormat formatter;
if(value - (int)value > 0.0)
formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish..
else
formatter = new DecimalFormat("0");
return formatter.format(value);
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,如果数字是自然数,我会得到 - 比如说 - 20000000 而不是 2E7 (等) - 没有任何小数点。
如果是十进制,我只能得到两位小数。
| 归档时间: |
|
| 查看次数: |
278639 次 |
| 最近记录: |