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

Ex .

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

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

181
Steven 1 Сен 2010 в 00:00

15 ответов

Лучший ответ

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

var n = 1.245000
var noZeroes = n.toString() // "1.245" 
133
Cristian Sanchez 31 Авг 2010 в 20:54

Простая математическая альтернатива использованию 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) );
-1
Gary 26 Июл 2018 в 14:18

Вот возможное решение:

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

eval(x) --> 1.234
eval(y) --> 1.234001
-1
sir_thursday 23 Июн 2014 в 23:52

Мне нужно было удалить любые конечные нули, но оставить как минимум 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

Логика:

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

0
Kevin H. 20 Июн 2019 в 03:45

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

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(), как указали другие.

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

Вот и все.

0
ed1nh0 22 Фев 2019 в 14:09

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

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;
}
2
BennyHilarious 1 Дек 2018 в 15:38

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

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

numeral(0.00000001).format('0[.][00000000]');
// "0.00000001"
4
Devon 25 Фев 2015 в 13:35

Чисто регулярное выражение

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

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

6
João Costa 20 Ноя 2018 в 16:41

Мне нужно было решить и эту проблему, когда 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
megasnort 30 Июл 2017 в 18:51

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

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

//output n = 0; 
// n = 3.14000; --> n = 3.14;
9
Amit Panasara 1 Апр 2019 в 05:24

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

var x = 1.234000*1; // becomes 1.234

var y = 1.234001*1; // stays as 1.234001
8
Koby Douek 13 Май 2018 в 07:07

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

В дополнение к обрезке конечных нулей мне также нужно было округлить и отформатировать выходные данные для текущей локали пользователя (т.е. 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

10
dperish 17 Май 2019 в 11:24

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

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

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

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

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

+(4).toFixed(2);
//-> 4
18
C. J. 1 Дек 2014 в 14:54

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

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" (поэтому нет ошибки времени выполнения)

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

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

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

27
w00t 22 Сен 2014 в 21:45

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

toFixed без дополнения

parseFloat(n.toFixed(4));

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

Number(n.toFixed(4));

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

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

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

var n = 1.23000;
 // n == 1.23;
214
MrP1us 13 Сен 2018 в 19:17