DecimalFormat - keep all decimal numbers
Asked Answered
S

2

8

I'm using DecimalFormat to format doubles into a String. This String is then integrated into my presentation layer.

  • Problem: I want to keep ALL decimals. Example: "12345678.123456789"
  • Question: What format should I use?
  • Remark: I use a different Locale to support multiple layouts.

Format: #.## -> This uses ALL numbers BEFORE the decimal, but ROUNDS the numbers AFTER the decimal.

I could use #.######### for the big decimal, but what if the decimal is even longer?

I found my small test program useful and want to share it with you.

Can you help me to show ALL decimals?

package be.softwarelab.numbers;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;

public class DecimalNumbersTest {

    private static final double NUMBER = 123456789.123456789;

    public static void main(String[] args) {

        String format01 = "#.";
        String format02 = "#.#";
        String format03 = "#.##";
        String format04 = "#.###";
        String format05 = "#.####"; 

        System.out.println("====== NUMBER ===== USA =====================================");
        showResult(NUMBER, format01, Locale.US);
        showResult(NUMBER, format02, Locale.US);
        showResult(NUMBER, format03, Locale.US);
        showResult(NUMBER, format04, Locale.US);
        showResult(NUMBER, format05, Locale.US);
        System.out.println("====== NUMBER ===== France ==================================");
        showResult(NUMBER, format01, Locale.FRANCE);
        showResult(NUMBER, format02, Locale.FRANCE);
        showResult(NUMBER, format03, Locale.FRANCE);
        showResult(NUMBER, format04, Locale.FRANCE);
        showResult(NUMBER, format05, Locale.FRANCE);
        System.out.println("=============================================================");
    }

    public static void showResult(double number, String format, Locale locale) {
        // Using a Locale to see the differences between regions.
        DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(locale);
        DecimalFormat formatter = new DecimalFormat (format, otherSymbols);

        // Create the String result
        String output = formatter.format(number);

        // Format the output for a nice presentation.
        System.out.format("    %s %11s = %20s\n", locale, format, output);
    }
}

This results in:

====== NUMBER ===== USA =====================================
en_US          #. =           123456789.
en_US         #.# =          123456789.1
en_US        #.## =         123456789.12
en_US       #.### =        123456789.123
en_US      #.#### =       123456789.1235
====== NUMBER ===== France ==================================
fr_FR          #. =           123456789,
fr_FR         #.# =          123456789,1
fr_FR        #.## =         123456789,12
fr_FR       #.### =        123456789,123
fr_FR      #.#### =       123456789,1235
=============================================================

Edit: One user mentioned a related question: How to nicely format floating numbers to String without unnecessary decimal 0? This question does not solve my problems, since it focuses on limiting the size, but I need to keep it as long as possible.

Sensual answered 28/10, 2016 at 11:50 Comment(6)
Possible duplicate of How to nicely format floating numbers to String without unnecessary decimal 0?. This answer should help.Sausage
Thanks for the feedback, but I did not find my solution in this answer. This is focused on limiting the size, but I need to keep it as long as possible. My customers need to see the accuracy. I also don't need trailing zero's.Sensual
Have you investigated in the suggested answer?Sausage
"I could use #.######### for the big decimal, but what if the decimal is even longer?" => What on earth are you measuring....? and is it really accurate to 10+ decimal places? or are these values simply result of calculation using less precise numbers?Ointment
@Flown: Yes, but didn't find a solution. Have you deeper insights? Should I follow the path of the related question further? I'm diving into this other way and keep you informed.Sensual
@Adam: Maybe my accuracy is a little confusing, but I don't know exactly how to describe this. I want all decimals for the presentation layer. A measuring device show all numbers, and we want to show the same. Thanks.Sensual
P
1

String.format might help you out here - NumberFormat

  private static void printfWithLocale(Locale locale, Double d){
    System.out.println("Output locale: " + locale.toString());
    String simpleOutputTeplate = "simpleOutputTeplate: %s";
    String refinedOutputTeplate = "refinedOutputTeplate: %.10f";

    System.out.println(String.format(locale, simpleOutputTeplate, d));
    System.out.println(String.format(locale, refinedOutputTeplate, d));

  }

  public static void main(String[] args) {

    Double d = new Double(3.1234567890123456789);

    printfWithLocale(Locale.US, d);
    System.out.println("");
    printfWithLocale(Locale.FRANCE, d);
  }

Code output:

Output locale: en_US
simpleOutputTeplate: 3.1234567890123457
refinedOutputTeplate: 3.1234567890

Output locale: fr_FR
simpleOutputTeplate: 3.1234567890123457
refinedOutputTeplate: 3,1234567890

You will notice that the %s (string) does not conform to the Locale, but does format the Double up to 17 decimal points. With String.format you can further refine the way your numbers are formatted in a string.

Panzer answered 28/10, 2016 at 13:12 Comment(1)
Does this mean there's actually no way to format a double directly using the locale while keeping all the decimals?Lateral
N
0

Since double does not exactly represent some numbers, it doesn't matter if you cut to a given length of decimals (like 17). See this other question for the explanation How many significant digits have floats and doubles in java?

Novocaine answered 28/10, 2016 at 13:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.