我想在没有指数形式的Java中打印double值。
double dexp = 12345678;
System.out.println("dexp: "+dexp);
它显示了这个E符号:1.2345678E7
。
我希望它像这样打印:12345678
防止这种情况的最佳方法是什么?
你可以使用printf()
和%f
:
double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);
这将打印dexp: 12345678.000000
。如果您不想要小数部分,请使用
System.out.printf("dexp: %.0f\n", dexp);
这使用documentation中解释的格式说明符语言。
原始代码中使用的默认toString()
格式拼写为here。
我认为每个人都有正确的想法,但所有答案都不是直截了当的。我可以看到这是一段非常有用的代码。这是一个可行的片段:
System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));
".8"
是您设置要显示的小数位数的地方。
我正在使用Eclipse,它没有问题。
希望这有用。我将不胜感激任何反馈!
当我使用它作为math.Eval()函数的字符串输入时,我的生产代码中出现了同样的问题,该函数采用类似“x + 20/50”的字符串
我看了几百篇文章......最后我因为速度而去了。并且因为Eval函数最终会将其转换回自己的数字格式,而math.Eval()不支持其他方法返回的尾随E-07,并且任何超过5 dp的内容对于我的应用程序来说都是太详细了。
现在,它已用于具有1,000多个用户的应用程序的生产代码中...
double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp
s display as: 0.00021
对于由double
表示的整数值,您可以使用此代码,这比其他解决方案快得多。
public static String doubleToString(final double d) {
// check for integer, also see https://stackoverflow.com/a/9898613/868941 and
// https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java
if (isMathematicalInteger(d)) {
return Long.toString((long)d);
} else {
// or use any of the solutions provided by others
return Double.toString(d);
}
}
// Java 8+
public static boolean isMathematicalInteger(final double d) {
return StrictMath.rint(d) == d && Double.isFinite(d);
}
我的解决方案:String str = String.format(“%。0f”,yourDouble);
将双精度数转换为正常数的五种不同方法:
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));
}
}
该程序打印:
2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000
哪些都是相同的价值。
Protip:如果你对为什么那些随机数字出现在双值的某个阈值之外感到困惑,这个视频解释:computerphile为什么0.1
+ 0.2
等于0.30000000000001
?
简而言之:
如果你想摆脱尾随零和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
说明:
为什么其他答案不适合我:
Double.toString()
或System.out.println
或FloatingDecimal.toJavaFormatString
使用科学记数法%f
,默认的小数精度为6,否则你可以对其进行硬编码,但如果你有更少的小数,它会导致额外的零加。例:
double myValue = 0.00000021d;
String.format("%.12f", myvalue); // Output: 0.000000210000
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
double myValue = 0.00000021d;
DecimalFormat df = new DecimalFormat("0");
df.setMaximumFractionDigits(340);
System.out.println(df.format(myvalue)); // Output: 0,00000021
使用ENGLISH语言环境可确保在程序运行的任何位置获得小数点分隔符。为什么使用340然后为setMaximumFractionDigits
?
两个原因:
setMaximumFractionDigits
接受一个整数,但它的实现具有DecimalFormat.DOUBLE_FRACTION_DIGITS
允许的最大位数,等于340Double.MIN_VALUE = 4.9E-324
所以340位数你肯定不会绕过你的双倍而失去精确度。你可以用DecimalFormat
试试。使用此类,您可以非常灵活地解析数字。
您可以准确设置要使用的模式。
以你的情况为例:
double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
我有另一个涉及BigDecimal的toPlainString()的解决方案,但这次使用的是字符串构造函数,这在javadoc中是推荐的:
此构造函数与Float.toString和Double.toString返回的值兼容。这通常是将float或double转换为BigDecimal的首选方法,因为它不会受到BigDecimal(double)构造函数的不可预测性的影响。
它看起来像最短的形式:
return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();
在Java 8之前,对于任何零值双打,结果为“0.0”,因此您需要添加:
if (myDouble.doubleValue() == 0)
return "0";
必须额外检查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();
}
这也可以复制/粘贴,以便与Float很好地配合使用。
只要您的号码是一个整数,这将有效:
double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);
如果double变量在小数点后具有精度,则会截断它。
我需要将一些双倍转换为货币值,并发现大多数解决方案都没问题,但不适合我。
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);
}
正如你所看到的,如果数字是自然的,我得到 - 比如说 - 20000000而不是2E7(等等) - 没有任何小数点。
如果它是十进制的,我只得到两位小数。
Java / Kotlin编译器将任何大于9999999(大于或等于1000万)的值转换为科学计数法即ie。 Epsilion符号。
例如:12345678转换为1.2345678E7
使用此代码可避免自动转换为科学记数法:
fun setTotalSalesValue(String total) {
var valueWithoutEpsilon = total.toBigDecimal()
/* Set the converted value to your android view using setText() function */
salesTextView.setText() = valueWithoutEpsilon.toPlainString()
}
以下代码检测所提供的数字是否以科学计数法表示。如果是这样,它以正常呈现方式表示,最多为“25”位。
static String convertFromScientificNotation(double number) {
// Check if in scientific notation
if (String.valueOf(number).toLowerCase().contains("e")) {
System.out.println("The scientific notation number'"
+ number
+ "' detected, it will be converted to normal representation with 25 maximum fraction digits.");
NumberFormat formatter = new DecimalFormat();
formatter.setMaximumFractionDigits(25);
return formatter.format(number);
} else
return String.valueOf(number);
}