Мне нужно получить два значения после последнего нуля в десятичном числе.
Я пытался использовать .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
Каков правильный способ достижения этого без обходных путей?
См. мой ответ, который использует Intl.NumberFormat для встроенного способа форматирования чисел до двух значащих цифр.
Я не думаю, что есть «правильный» способ сделать это, потому что на самом деле это не так; вам нужна произвольная точность числа, основанная на том, где появляются ненулевые значения.
Я предполагаю, что это что-то вроде отображения, поэтому имеет смысл, что это делается, когда вы конвертируете число в строку для отображения.
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
Гораздо ярче моего. Хороший ответ.
Все ответы помогли, но ваш сделал работу. Спасибо.
Следуйте приведенному ниже коду:
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 хочет сохранить нули после запятой.
Сначала подсчитайте, сколько нулей стоит после запятой.
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
Вам нужны первые 2 цифры, которые не равны нулю, я не думаю, что есть метод без «обходных путей». А именно, затирание строк, что вы хотите.