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:如何用第十个指数格式化字符串数字的主要内容,如果未能解决你的问题,请参考以下文章

如何用两个字符串生成一个唯一的数字

Oracle中如何用SQL把字符串转换成整型

Oracle中如何用SQL把字符串转换成整型

批处理如何用正则提取字符串中间的数字,和结尾的数字

万变不离核心基础第十关——print函数的核心功能

如何用正则表达式 匹配正确的imei串号呢!imei格式:由0-9数字组成的15或者17位的串号?