Например, когда я анализирую строку «12345678901234567890», чтобы удвоить ее с помощью Double.parseDouble (), он возвращает значение «12345678901234567000», поскольку он может содержать до 17 цифр.

Я хочу проверить этот сценарий, и пользователю должно быть разрешено передавать только 17 цифр. Как мне это сделать?

Пример: 1.2345678901234567890 недопустимо, потому что в нем более 17 цифр. 1.2345E + 10 действительно

-3
rakhesh 9 Дек 2019 в 23:49
2
Будьте осторожны с этим. Вы можете использовать что-то вроде if (myString.length() > 17), но это не гарантия того, что преобразование в double не приведет к округлению.
 – 
Dawood ibn Kareem
9 Дек 2019 в 23:52
Сделать это правильно с помощью регулярных выражений будет намного сложнее, чем вы думаете. В качестве тривиального примера: «12345678901234567890» не помещается в Double без потери точности, но «12345678901234567000» подходит , даже несмотря на то же количество цифр. Таким образом, вам нужно будет проверить не только длину строки, но и то, сколько цифр «релевантны». И нет, это не всегда будет «0 в порядке, все остальное - нет», потому что double заботится о том, что можно представить в двоичном формате, десятичное представление интуитивно не соответствует этому.
 – 
Joachim Sauer
9 Дек 2019 в 23:54
Из любопытства вы пробовали System.out.println(Double.parseDouble("12345678901234568000"));? Результат может быть не таким, как вы ожидаете. В общем, вы можете доверять только первым 15 значащим цифрам double.
 – 
Dawood ibn Kareem
10 Дек 2019 в 08:21

2 ответа

Предполагая, что я понимаю вашу цель ограничения количества цифр, это может помочь решить проблему.

Контрольные примеры

      String[] vals = {
            "12345678901234567890", "123456789091919191919",
            "182828282.18282828", "182828282.182828282", "191929e10",
            "192929.22929e10"
      };

Попробуйте разобрать их

      for (String v : vals) {
         // remove possible decimal point and signs
         String test = v.replaceAll("[.+-]", "");
         // remove any exponents at end of string
         test = test.replace("\\D+.*", "");
         if (test.length() > 17) {
            System.out.println(v + " has too many digits");
            continue;
         }
         double d = Double.parseDouble(v);
         System.out.println(v + " parses to " + d);
      }
0
WJS 10 Дек 2019 в 20:33

Попробовал что-то вроде этого, который может считать цифры, используя функцию разделения

String input="12345678901234567E100";
    String inputWithoutSign;
    int lengthFullNumber;
    int lengthFraction;
    double v = Double.parseDouble(input);
    if(input.startsWith("+") || input.startsWith("-")){
        inputWithoutSign = input.split("[-+]",2)[1];
    }
    else inputWithoutSign = input;

    String num = inputWithoutSign.split("[eE]", 2)[0];

    if(num.indexOf('.') == -1){
        lengthFullNumber = num.length();
        lengthFraction = 0;
    }else{
        String[] splitNum = num.split("\\.", 2);

        lengthFullNumber = splitNum[0].length();

        lengthFraction = splitNum[1].length();
    }

    System.out.println("length:"+(lengthFullNumber+lengthFraction));
0
rakhesh 10 Дек 2019 в 00:36
1
Зачем это нужно? Не было бы проще использовать Double.parseDouble () и поймать исключение для недопустимого ввода?
 – 
WJS
10 Дек 2019 в 01:40
Я не хочу терять цифры при вводе пользователя. В примере «12345678901234567890» parseDouble дает мне «12345678901234567000».
 – 
rakhesh
10 Дек 2019 в 10:35