Java:如何格式化具有第十个指数的字符串数字

发布于 2024-10-22 09:55:39 字数 305 浏览 1 评论 0原文

我有一个数字作为字符串,如下所示:“9.756088256835938E-4”,但我只能使用指定数量的字符(在这种特殊情况下为 9 个字符)。所以我想要这样的东西:“9.7561E-4”。我已经尝试将字符串转换为双精度,然后使用格式方法来获得更少的字符,但我没有得到正确的解决方案。

问题是我需要十个指数输出,因为有些数字比我拥有的字符数长。如果可能的话,数字应该不显示十指数,如果不行就使用十指数。

正确的舍入也很好。

它应该适用于负数。 (减号需要一个字符!!!)

是否有一种格式函数可以定义输出字符串的最大长度?有什么想法吗?

I have a number as a string like this: "9.756088256835938E-4" but I only can use a specified number of characters (in this special case 9 char). So I want to have something like this: "9.7561E-4". I already tried to convert the String to a Double and then used the format method to get a less characters but I don't got a correct solution.

The problem is that I need ten exponential output since some numbers are longer than the number of characters I have. If it is possible, the number should be displayed with no ten exponent, if not just use the ten exponent.

Also correct rounding would be good.

And it should work for negative numbers. (minus needs one character!!!)

Is there a format function where I can define the maximum length of the output string? Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦里的微风 2024-10-29 09:55:39

我无法找到一个可以涵盖您描述的所有情况的单一格式模式。但我认为这是一个有效的逻辑组合:

   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

I'm having trouble findind a single format pattern that will cover all of the cases that you described. But here's a combination of logic that I think works:

   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
   }

The "G" in the pattern instructs the formatter to forego the use of the exponent when it will allow for the same or better precision. We grow up to the maximum length and stop when our output string is 10 characters. I think you could take the same approach with a DecimalFormat, but I'm more familiar with Formatter.

纸伞微斜 2024-10-29 09:55:39

看到马克的示例满足您的要求,我更新了我的答案以显示 DecimalFormat 实现。我使用了马克的测试用例。这绝对是一个更丑陋的选择,因为没有简单的方法来打开/关闭指数。与 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;
}

这让我想起了类似问题,OP 的数字只有 5 个左右的空格,并且只有在有足够的空间时才想显示小数。但不想使用指数,而是想使用后缀(k,m等)

Seeing the Mark's example meet your requirements, I updated my answer to show the DecimalFormat implementation. I used Mark's test cases. It is definitely an uglier option because there is no easy way to turn on/off exponents. The only advantage over the String.format option is that it handles very small numbers well.

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;
}

This reminded me of a similar question where the OP only had 5 or so spaces for a number and wanted to show a decimal only when there was enough space. But instead of exponents, wanted to use a suffix of (k,m, etc)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文