Получить последние два значения после нулей в десятичной дроби

Мне нужно получить два значения после последнего нуля в десятичном числе.

Я пытался использовать .toFixed() и .toPrecision(), но не могу добиться того, что мне нужно.

Я пытаюсь добиться следующего: -

let num1 = 0.028234234234234234
console.info(num1)
// 0.028

let num2 = 0.0000028234234234
console.info(num2)
// 0.0000028

let num3 = 0.0000000002823423
console.info(num3)
// 0.00000000028

Но что у меня есть:

let num1 = 0.000002800
console.info(num1.toFixed(7))
// 0.000002800

console.info(num1.toPrecision(7))
// 0.000002800000

Каков правильный способ достижения этого без обходных путей?

Вам нужны первые 2 цифры, которые не равны нулю, я не думаю, что есть метод без «обходных путей». А именно, затирание строк, что вы хотите.

Jamiec 22.02.2023 09:35

См. мой ответ, который использует Intl.NumberFormat для встроенного способа форматирования чисел до двух значащих цифр.

phuzi 22.02.2023 12:17
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Интервьюер: Почему '[] instanceof Object' возвращает "true"?
Интервьюер: Почему '[] instanceof Object' возвращает "true"?
Все мы знаем, что [] instanceof Array возвращает true, но почему [] instanceof Object тоже возвращает true?
Абстрактное синтаксическое дерево (AST) и как оно работает с ReactJS
Абстрактное синтаксическое дерево (AST) и как оно работает с ReactJS
Абстрактное синтаксическое дерево (AST) - это древовидная структура данных, которая представляет структуру и иерархию исходного кода на языке...
1
2
62
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Я не думаю, что есть «правильный» способ сделать это, потому что на самом деле это не так; вам нужна произвольная точность числа, основанная на том, где появляются ненулевые значения.

Я предполагаю, что это что-то вроде отображения, поэтому имеет смысл, что это делается, когда вы конвертируете число в строку для отображения.

function numberWithFirstTwoNonZeroDigits(input){
   var parts = input.toFixed(30).toString().split(".");
   var decimals = parts[1].split('').reduce((acc,i) => {
       if (acc.numDigits < 2){
          acc.result += i;
          if (i != "0") acc.numDigits++;
       }
       return acc;
   },{result:'',numDigits:0});
   
   return `${parts[0]}.${decimals.result}`;
}

let num1 = 0.028234234234234234
console.info(numberWithFirstTwoNonZeroDigits(num1))
// 0.028

let num2 = 0.0000028234234234
console.info(numberWithFirstTwoNonZeroDigits(num2))
// 0.0000028

let num3 = 0.0000000002823423
console.info(numberWithFirstTwoNonZeroDigits(num3))
// 0.00000000028
Ответ принят как подходящий

Как уже упоминалось, я не думаю, что есть один «правильный» способ сделать это. Если это для целей отображения, вы можете использовать простую замену Regex.

Я не знаю всех ваших тестовых случаев, но на основе того, что вы предоставили, может работать что-то вроде следующего:

function format(num) {
  return num.toFixed(30).toString().replace(/(\d+)\.([0]+\d\d)(.*)/g, '$1.$2');
}

let num1 = 0.028234234234234234
console.info(format(num1))
// 0.028

let num2 = 0.0000028234234234
console.info(format(num2))
// 0.0000028

let num3 = 0.0000000002823423
console.info(format(num3))
// 0.00000000028

let num4 = 0.000000000000002823423
console.info(format(num4))
// 0.0000000000000028

Гораздо ярче моего. Хороший ответ.

Jamiec 22.02.2023 10:25

Все ответы помогли, но ваш сделал работу. Спасибо.

James 22.02.2023 10:54

Следуйте приведенному ниже коду:

       

     function getNum(num) {
      const arrNum = num.toString().split(".");
      const endNums = [];
      if (arrNum[1] !== "0") {
        let count = 0;
        let i = 0;
        while (count < 2 && i < arrNum[1].length) {
                                  endNums.push(arrNum[1][i]);

          if (arrNum[1][i] !== "0") {
            count++;
          }

          i++;
        }
      }
      return '0.'+endNums.join(""); 
    }

    console.info(getNum(0.0000021343432));

К сожалению, OP хочет сохранить нули после запятой.

phuzi 22.02.2023 12:19

Сначала подсчитайте, сколько нулей стоит после запятой.

const num = 0.0000000002823423;
const str = num.toFixed(20); // convert to string with 20 decimal places
const decimalIndex = str.indexOf('.');
const numZeros = str.slice(decimalIndex + 1).match(/^0*/)[0].length;

Здесь toFixed() используется для преобразования числа num в строку с 20 знаками после запятой. Это гарантирует, что мы зафиксируем все нули после запятой. Затем используется метод indexOf() для нахождения индекса десятичной точки в строке. Метод slice() используется для получения подстроки, которая начинается после запятой. Метод match() с регулярным выражением /^0*/ используется для поиска последовательности из нуля или более нулей в начале подстроки. Затем, используя метод длины, мы можем получить количество нулей.

После этого наша работа довольно проста, просто добавьте 2 числа, которые вы сохраняете после нулей.

const formattedNum = num.toFixed(numZeros + 2);
console.info(formattedNum);// 0.00000000028

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

Вам следует использовать API интернационализации и встроенное форматирование чисел Intl.NumberFormat.

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

Установив maximumSignificantDigits: 2, вы ограничиваете вывод двумя значащими цифрами, которые вам нужны. Параметр maximumFractionDigits: 20 включает максимально возможное количество начальных нулей.

ПРИМЕЧАНИЕ: 20 — это максимально допустимое значение для maximumFractionDigits, поэтому, если вы используете числа меньше этого, вы можете столкнуться с проблемами.

const formatter = new Intl.NumberFormat('en', {
  maximumSignificantDigits: 2,
  maximumFractionDigits: 20
});

let num1 = 0.028234234234234234
console.info(formatter.format(num1))
// 0.028

let num2 = 0.0000028234234234
console.info(formatter.format(num2))
// 0.0000028

let num3 = 0.0000000002823423
console.info(formatter.format(num3))
// 0.00000000028

Другие вопросы по теме