Как дублировать функциональность Java DecimalFormat? - PullRequest
0 голосов
/ 03 мая 2020

Мне нужно отобразить на экране компьютера двойное значение, отформатированное с помощью DecimalFormat, и передать то же значение в аппаратную цифру. c отображать в виде двух целых чисел: целую часть и дробную часть, дробную часть, выраженную как целое число 1 /1000ths.

Через два часа я все еще не могу понять, как это сделать, чтобы два отображаемых значения всегда совпадали.

Независимо от того, как я округляю значения и какой режим округления я использую всегда терпит неудачу для некоторых значений.

Чтобы поэкспериментировать с этим, я создал следующий код:

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Locale;

public class TestRounding {

    public static void main(String[] args) {
        Locale.setDefault(Locale.ENGLISH);
        DecimalFormat f = new DecimalFormat("0.000");
        f.setRoundingMode(RoundingMode.HALF_UP);

        if (true) {
            for (int i = 0; i < 10000000; i++) {
                double d = i / 10000000.0; // test with this value
                long l = Math.round(d*1000); // get d as 1/1000ths rounded
                int ip = (int) (l / 1000); // get the integer parts
                int fp = (int) (l % 1000); // get the fractional in 1/1000ths
                // convert to string for comparison agains DecilmalFormat formatted string
                String is = Integer.toString(ip);
                String fs = Integer.toString(fp);
                while (fs.length() < 3)
                    fs = "0" + fs;
                String rs = is + "." + fs;
                String fv = f.format(d);
                // check if they match
                if (!rs.equals(fv))
                    System.out.println(d + " => " + rs + " != " + fv);

            }
            System.exit(0);
            ;
        }
    }

}

Единственный код, который работает, это чудовище:

// Get a formatter that always has decimal POINT
DecimalFormatSymbols decimalpoint = new DecimalFormatSymbols();
decimalpoint.setDecimalSeparator('.');
DecimalFormat format  = new DecimalFormat("0.000", decimalpoint);

// format the double value as string and split at the decimal point
String s = format(d);
int pi = s.indexOf(".");
String is = s.substring(0, pi);
String fs = s.substring(pi + 1);
// convert the integer and decimal parts separately
int ip = Integer.parseInt(is);
int fp = Integer.parseInt(fs);
// in case the fractional part is not in 1/1000ths (for example the format string was 0.00 or 0.0000)
int dd = fs.length();
for (int j = dd; j < 3; j++)
    fp *= 10;
for (int j = dd; j > 3; j++)
    fp /= 10;
...