Java:如何用第十个指数格式化字符串数字
Posted
技术标签:
【中文标题】Java:如何用第十个指数格式化字符串数字【英文标题】:Java: How to format String number with tenth exponent 【发布时间】:2011-03-17 13:53:31 【问题描述】:我有一个数字作为这样的字符串:“9.756088256835938E-4”但我只能使用指定数量的字符(在这种特殊情况下为 9 个字符)。所以我想要这样的东西:“9.7561E-4”。我已经尝试将 String 转换为 Double ,然后使用 format 方法来获得更少的字符,但我没有正确的解决方案。
问题是我需要十个指数输出,因为有些数字比我拥有的字符数长。如果可能,数字应该不显示十个指数,如果不是只使用十个指数。
正确的舍入也很好。
它应该适用于负数。 (减去需要一个字符!!!)
是否有可以定义输出字符串最大长度的格式函数?有什么想法吗?
【问题讨论】:
许多类似的帖子:***.com/q/4429163/122607、***.com/q/4457722/122607、***.com/q/649447/122607、***.com/q/2525492/122607、***.com/q/3008800/122607 @LordTorg,我认为 OP 正在询问使用第十个指数,这些问题都没有解决,它们都关注小数位数。 @jzd,这是可能的......这取决于 OP 试图用“十指数输出”/“十指数”说什么。 @LordTorg,我同意,OP 应该包含几个带有边缘情况的示例,以便更清楚。 我不确定它是如何用英语调用的(第十个指数),但 jzd 是对的,我的重点是这种指数格式。我已经找到了大部分帖子,但它们对我的问题没有帮助。还是谢谢 【参考方案1】:我很难找到涵盖您描述的所有情况的单一格式模式。但这是我认为可行的逻辑组合:
public static void main(String[] args) throws Exception
// 97.560883
System.out.println(formatNum(Double.parseDouble("9.756088256835938E+1")));
// 9.756E+11
System.out.println(formatNum(Double.parseDouble("9.756088256835938E+11")));
// 0.0009756
System.out.println(formatNum(Double.parseDouble("9.756088256835938E-4")));
// -9.8E+111
System.out.println(formatNum(Double.parseDouble("-9.756088256835938E+111")));
private static final int MAX_LENGTH = 9;
private static String formatNum(double number)
String out = null;
for ( int i = 0; i < MAX_LENGTH; i++ )
String format = "%." + i + "G";
out = String.format(format, number);
if ( out.length() == MAX_LENGTH )
return out;
return out; //the best we can do
模式中的“G”指示格式化程序在允许相同或更好的精度时放弃使用指数。我们增长到最大长度并在输出字符串为 10 个字符时停止。我认为您可以对DecimalFormat
采取相同的方法,但我更熟悉Formatter
。
【讨论】:
不错的功能,但你知道为什么 String.format(format, number);当 number = 0 时抛出 java.lang.ArrayIndexOutOfBoundsException?【参考方案2】:看到 Mark 的示例满足您的要求,我更新了答案以显示 DecimalFormat
实现。我使用了 Mark 的测试用例。这绝对是一个丑陋的选择,因为没有简单的方法来打开/关闭指数。与 String.format
选项相比的唯一优势是它可以很好地处理非常小的数字。
public static void main(String[] args) throws Exception
// 97.560883
System.out.println(formatNum(Double.parseDouble("9.756088256835938E+1")));
// 9.756E+11
System.out.println(formatNum(Double.parseDouble("9.756088256835938E+11")));
// 0.0009756
System.out.println(formatNum(Double.parseDouble("9.756088256835938E-4")));
// -9.8E+111
System.out.println(formatNum(Double.parseDouble("-9.756088256835938E+111")));
private static final int MAX_LENGTH = 9;
private static String formatNum(double number)
int digitsAvailable = MAX_LENGTH - 2;
if (Math.abs(number) < Math.pow(10, digitsAvailable)
&& Math.abs(number) > Math.pow(10, -digitsAvailable))
String format = "0.";
double temp = number;
for (int i = 0; i < digitsAvailable; i++)
if ((temp /= 10) < 1)
format += "#";
return new DecimalFormat(format).format(number);
String format = "0.";
for (int i = 0; i < digitsAvailable; i++)
format += "#";
String r = new DecimalFormat(format + "E0").format(number);
int lastLength = r.length() + 1;
while (r.length() > MAX_LENGTH && lastLength > r.length())
lastLength = r.length();
r = r.replaceAll("\\.?[0-9]E", "E");
return r;
这让我想起了similar question,其中 OP 只有 5 个左右的空格来表示一个数字,并且只有在有足够的空间时才想显示一个小数。但不是指数,而是想使用 (k,m, etc) 的后缀
【讨论】:
是的,您的链接似乎实现了类似的。我没有在我的上下文中找到这篇文章,我最初是在寻找一个开箱即用的 java 函数(似乎没有),因为标准双转换似乎也在第十指数和正常格式之间自动切换。我想到了配置标准行为的可能性。谢谢以上是关于Java:如何用第十个指数格式化字符串数字的主要内容,如果未能解决你的问题,请参考以下文章