Удалить незначительные конечные нули из числа?

Я пропустил стандартный вызов API, который удаляет конечные несущественные нули из числа?

Исх.

var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001

Number.toFixed() и Number.toPrecision() не совсем то, что я ищу.

Ответ 1

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

var n = 1.245000
var noZeroes = n.toString() // "1.245" 

Ответ 2

У меня был похожий экземпляр, где я хотел использовать .toFixed() там, где это необходимо, но я не хотел, чтобы .toFixed() его, когда это было не так. Поэтому я закончил использование parseFloat вместе с toFixed.

toFixed без прокладки

parseFloat(n.toFixed(4));

Другой вариант, который делает почти то же самое
Этот ответ может помочь вашему решению

Number(n.toFixed(4));

toFixed будет округлять /toFixed число до определенной длины, а также преобразовывать его в строку. Преобразование этого числа в числовой тип не только сделает номер более безопасным для использования арифметически, но также автоматически отбросит любые конечные 0. Например:

var n = "1.234000";
    n = parseFloat(n);
 // n is 1.234 and in number form

Потому что даже если вы определяете число с завершающими нулями, они отбрасываются.

var n = 1.23000;
 // n == 1.23;

Ответ 3

Сначала я использовал комбинацию ответов мати-лиры и гари:

r=(+n).toFixed(4).replace(/\.0+$/,'')

Результаты:

  • 1234870.98762341: "1234870.9876"
  • 1230009100: "1230009100"
  • 0.0012234: "0.0012"
  • 0.1200234: "0.12"
  • 0.000001231: "0"
  • 0.10001: "0.1000"
  • "asdf": "NaN" (поэтому нет ошибки времени выполнения)

Несколько проблемный случай - 0.10001. Я закончил использовать эту более длинную версию:

    r = (+n).toFixed(4);
    if (r.match(/\./)) {
      r = r.replace(/\.?0+$/, '');
    }
  • 1234870.98762341: "1234870.9876"
  • 1230009100: "1230009100"
  • 0.0012234: "0.0012"
  • 0.1200234: "0.12"
  • 0.000001231: "0"
  • 0.10001: "0.1"
  • "asdf": "NaN" (поэтому нет ошибки времени выполнения)

Обновление. И это более новая версия Gary (см. комментарии):

r=(+n).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1')

Это дает те же результаты, что и выше.

Ответ 4

Метод toFixed при необходимости выполнит соответствующее округление. Он также добавит конечные нули, что не всегда идеально.

(4.55555).toFixed(2);
//-> "4.56"

(4).toFixed(2);
//-> "4.00"

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

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4

Ответ 5

Мне также пришлось решить эту проблему, когда Django отображал значения десятичного типа в текстовом поле. Например. когда значение "1" было значением. Он будет показывать "1.00000000". Если "1.23" было значением, оно отображало бы "1.23000000" (в случае установки "decimal_places" 8)

Использование parseFloat для меня не было возможным, так как это возможно, оно не возвращает точно такое же значение. toFixed не был вариантом, так как я не хотел ничего крутить, поэтому я создал функцию:

function removeTrailingZeros(value) {
    value = value.toString();

    # if not containing a dot, we do not need to do anything
    if (value.indexOf('.') === -1) {
        return value;
    }

    # as long as the last character is a 0 or a dot, remove it
    while((value.slice(-1) === '0' || value.slice(-1) === '.') && value.indexOf('.') !== -1) {
        value = value.substr(0, value.length - 1);
    }
    return value;
}

Ответ 6

У меня было в основном то же самое требование, и я обнаружил, что для этой функции нет встроенного механизма.

В дополнение к обрезке конечных нулей мне также необходимо было округлить и отформатировать выходные данные для текущей локали пользователя (т.е. 123 456,789).

Вся моя работа над этим была включена в виде prettyFloat.js(MIT Licensed) на GitHub: https://github.com/dperish/prettyFloat.js


Примеры использования:

prettyFloat(1.111001, 3) // "1.111"
prettyFloat(1.111001, 4) // "1.111"
prettyFloat(1.1111001, 5) // "1.1111"
prettyFloat(1234.5678, 2) // "1234.57"
prettyFloat(1234.5678, 2, true) // "1,234.57" (en-us)


Обновлено - август 2018 г.


Все современные браузеры теперь поддерживают Интернационализацию API ECMAScript, которая обеспечивает сравнение строк с учетом языка, форматирование чисел и форматирование даты и времени.

let formatters = {
    default: new Intl.NumberFormat(),
    currency: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
    whole: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
    oneDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 1, maximumFractionDigits: 1 }),
    twoDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 })
};

formatters.twoDecimal.format(1234.5678);  // result: "1,234.57"
formatters.currency.format(28761232.291); // result: "$28,761,232"

Для старых браузеров вы можете использовать этот полифилл: https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en

Ответ 7

Чистый регулярный вызов

n.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1');

Интересно, почему никто не дал!

Ответ 8

Вы можете попробовать это, чтобы минимизировать плавающие числа

var n = 0.0000;
n = parseFloat(n.toString()); 

//output n = 0; 
// n = 3.14000; --> n = 3.14;

Ответ 9

Ни один из этих решений не работал у меня для очень маленьких чисел. http://numeraljs.com/ решил это для меня.

parseFloat(0.00000001.toFixed(8));
// 1e-8

numeral(0.00000001).format('0[.][00000000]');
// "0.00000001"

Ответ 10

Как насчет того, чтобы просто умножать один на один?

var x = 1.234000*1; // becomes 1.234

var y = 1.234001*1; // stays as 1.234001

Ответ 11

Если вы не можете использовать Floats по какой-либо причине (например, связанные с денежными средствами) и уже начинаете с строки, представляющей правильный номер, вы можете найти это решение удобным. Он преобразует строку, представляющую число, в строку, представляющую число без конечных нулей.

function removeTrailingZeroes( strAmount ) {
    // remove all trailing zeroes in the decimal part
    var strDecSepCd = '.'; // decimal separator
    var iDSPosition = strAmount.indexOf( strDecSepCd ); // decimal separator positions
    if ( iDSPosition !== -1 ) {
        var strDecPart = strAmount.substr( iDSPosition ); // including the decimal separator

        var i = strDecPart.length - 1;
        for ( ; i >= 0 ; i-- ) {
            if ( strDecPart.charAt(i) !== '0') {
                break;
            }
        }

        if ( i=== 0 ) {
            return strAmount.substring(0, iDSPosition);
        } else {
            // return INTPART and DS + DECPART including the rightmost significant number
            return strAmount.substring(0, iDSPosition) + strDecPart.substring(0,i + 1);
        }
    }

    return strAmount;
}

Ответ 12

Легкий способ избавиться от конечных нулей с помощью big.js

1.234000 => 1.234

let x = new Big("1.2340000");
x = new Big(x.toFixed(5)); //decide how many decimal digits you want

console.log(x.toString()); //1.234

Ответ 13

Прочитав все ответы - и комментарии - я закончил с этим:

function isFloat(n) {
    let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n)) : n;
    return number;
}

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

Так:

isFloat(1.234000);     // = 1.234;
isFloat(1.234001);     // = 1.234001
isFloat(1.2340010000); // = 1.234001

Если вы хотите ограничить десятичные toFixed(), используйте toFixed() как указали другие.

let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n).toFixed(3)) : n;

Это.

Ответ 14

Мне нужно было удалить любые конечные нули, но оставить как минимум 2 десятичных знака, включая все нули.
Числа, с которыми я работаю, представляют собой 6 строк десятичных чисел, сгенерированных .toFixed(6).

Ожидаемый результат:

var numstra = 12345.000010 // should return 12345.00001
var numstrb = 12345.100000 // should return 12345.10
var numstrc = 12345.000000 // should return 12345.00
var numstrd = 12345.123000 // should return 12345.123

Решение:

var numstr = 12345.100000

while (numstr[numstr.length-1] === "0") {           
    numstr = numstr.slice(0, -1)
    if (numstr[numstr.length-1] !== "0") {break;}
    if (numstr[numstr.length-3] === ".") {break;}
}

console.log(numstr) // 12345.10

Логика:

Запустите функцию цикла, если последний символ строки равен нулю.
Удалите последний символ и обновите строковую переменную.
Если в обновленной строке последний символ не равен нулю, завершите цикл.
Если обновленная строка с третьего по последний символ является плавающей точкой, конец цикла.

Ответ 15

Здесь возможно решение:

var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001

eval(x) --> 1.234
eval(y) --> 1.234001

Ответ 16

Просто простая математическая альтернатива использованию toFixed

function truncateNumber( num, precision ){
    let c = Math.pow(10,precision);
    return Math.trunc( num*c )/c;
}
    
console.log( truncateNumber(1234.5678, 4) );
console.log( truncateNumber(1234.56, 4) );