Подтвердить что ты не робот

Как отформатировать float в javascript?

В JavaScript, при преобразовании из float в строку, как я могу получить всего 2 цифры после десятичной точки? Например, 0,34 вместо 0,3445434.

4b9b3361

Ответ 1

var result = Math.round(original*100)/100;

Особенности, если код не является самоочевидным.

изменить:... или просто использовать toFixed, как предложено Tim Büthe. Забыл тот, спасибо (и upvote) за напоминание:)

Ответ 2

Существуют функции для округления чисел. Например:

var x = 5.0364342423;
print(x.toFixed(2));

напечатает 5.04.

EDIT: Fiddle

Ответ 3

Будьте осторожны при использовании toFixed():

Во-первых, округление числа выполняется с использованием двоичного представления числа, что может привести к неожиданному поведению. Например

(0.595).toFixed(2) === '0.59'

вместо '0.6'.

Во-вторых, есть ошибка IE с toFixed(). В IE (по крайней мере, до версии 7, не проверял IE8), выполняется следующее:

(0.9).toFixed(0) === '0'

Может быть хорошей идеей следовать предложению kkyy или использовать пользовательскую функцию toFixed(), например

function toFixed(value, precision) {
    var power = Math.pow(10, precision || 0);
    return String(Math.round(value * power) / power);
}

Ответ 4

Еще одна проблема, о которой нужно знать, заключается в том, что toFixed() может создавать ненужные нули в конце номера. Например:

var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"

Идея состоит в том, чтобы очистить вывод, используя RegExp:

function humanize(x){
  return x.toFixed(6).replace(/\.?0*$/,'');
}

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

humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"

Ответ 5

var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding

Ответ 6

Существует проблема со всеми этими решениями, использующими множители. И кким, и решения Кристофа ошибочны, к сожалению.

Пожалуйста, проверьте свой код на номер 551.175 с двумя десятичными знаками - он будет округлен до 551,17, тогда как он должен быть 551,18! Но если вы проверите напр. 451.175 это будет нормально - 451.18. Поэтому на первый взгляд трудно обнаружить эту ошибку.

Проблема заключается в умножении: try 551.175 * 100 = 55117.49999999999 (ups!)

Итак, моя идея - обработать его с помощью toFixed() перед использованием Math.round();

function roundFix(number, precision)
{
    var multi = Math.pow(10, precision);
    return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}

Ответ 7

Эта проблема, вероятно, стоит еще одного ответа: как упоминалось Dony и ArteQ, на округление влияет потеря точности (то есть 0.5 может стать 0.49999...). Следствием этого является то, что округление не является half up, а half down или любой другой метод согласованного округления и даст непоследовательный результат независимо от используемого вами метода.

В действительности toFixed также влияет:

(0.335).toFixed(2) == 0.34
(0.345).toFixed(2) == 0.34

Итак, какой бы метод вы ни использовали, если вам нужна согласованность в округлении, вам лучше добавить (или удалить) epsilon.

например. для округления с половиной округления с помощью toFixed:

var epsilon = 0.001;
(0.335 + epsilon).toFixed(2) == 0.34;
(0.345 + epsilon).toFixed(2) == 0.35;

То же самое, если вы создаете свою собственную функцию, добавьте/удалите epsilon перед вычислением.

Обновление:

Как указано матиасами, у этих методов есть недостаток: какое значение эпсилона, 0.334999999... будет всегда округлено с 0,34 вместо 0,35. Поэтому мы имеем согласованность, но не "стандартное округление".

Ответ 8

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

function roundOf(n, p) {
    const n1 = n * Math.pow(10, p + 1);
    const n2 = Math.floor(n1 / 10);
    if (n1 >= (n2 * 10 + 5)) {
        return (n2 + 1) / Math.pow(10, p);
    }
    return n2 / Math.pow(10, p);
}

// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34

Теперь вы можете безопасно отформатировать это значение с помощью toFixed (p). Итак, с вашим конкретным случаем:

roundOf(0.3445434, 2).toFixed(2); // 0.34

Ответ 9

function trimNumber(num, len) {
  const modulu_one = 1;
  const start_numbers_float=2;
  var int_part = Math.trunc(num);
  var float_part = String(num % modulu_one);
      float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
  return int_part+'.'+float_part;
}

Ответ 10

Возможно, вам также понадобится десятичный разделитель? Вот функция, которую я только что сделал:

function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
    if (num < 0)
    {
        num = -num;
        sinal = -1;
    } else
        sinal = 1;
    var resposta = "";
    var part = "";
    if (num != Math.floor(num)) // decimal values present
    {
        part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
        while (part.length < casasDec)
            part = '0'+part;
        if (casasDec > 0)
        {
            resposta = sepDecimal+part;
            num = Math.floor(num);
        } else
            num = Math.round(num);
    } // end of decimal part
    while (num > 0) // integer part
    {
        part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
        num = Math.floor(num/1000);
        if (num > 0)
            while (part.length < 3) // 123.023.123  if sepMilhar = '.'
                part = '0'+part; // 023
        resposta = part+resposta;
        if (num > 0)
            resposta = sepMilhar+resposta;
    }
    if (sinal < 0)
        resposta = '-'+resposta;
    return resposta;
}

Ответ 11

Невозможно избежать несогласованного округления цен с x.xx5 как фактическое значение с использованием либо умножения, либо деления. Если вам нужно рассчитать правильные цены на стороне клиента, вы должны хранить все суммы в центах. Это связано с характером внутреннего представления числовых значений в JavaScript. Обратите внимание, что Excel страдает от одних и тех же проблем, поэтому большинство людей не замечают небольших ошибок, вызванных этим феноменом. Однако ошибки могут накапливаться всякий раз, когда вы добавляете много вычисленных значений, существует целая теория вокруг этого, включающая порядок вычислений и другие методы, чтобы минимизировать ошибку в конечном результате. Чтобы подчеркнуть проблемы с десятичными значениями, обратите внимание, что 0,1 + 0,2 не точно равно 0,3 в JavaScript, а 1 + 2 равно 3.

Ответ 12

/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) { 
    if (!nbDec) nbDec = 100;
    var a = Math.abs(x);
    var e = Math.floor(a);
    var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
    var signStr = (x<0) ? "-" : " ";
    var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
    var eStr = e.toString();
    return signStr+eStr+"."+decStr;
}

prettyFloat(0);      //  "0.00"
prettyFloat(-1);     // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5);    //  "0.50"

Ответ 13

Я использую этот код для форматирования поплавков. Он основан на toPrecision() но он удаляет ненужные нули. Я бы приветствовал предложения о том, как упростить регулярное выражение.

function round(x, n) {
    var exp = Math.pow(10, n);
    return Math.floor(x*exp + 0.5)/exp;
}

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

function test(x, n, d) {
    var rounded = rnd(x, d);
    var result = rounded.toPrecision(n);
    result = result.replace(/\.?0*$/, '');
    result = result.replace(/\.?0*e/, 'e');
    result = result.replace('e+', 'e');
    return result;  
}

document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');

Ответ 14

Если вы хотите строку без округления, вы можете использовать этот RegEx (возможно, это не самый эффективный способ... но это действительно легко)

(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'

Ответ 15

var a=1e-8;
a.toFixed(15).replace(/\.?0+$/,'')
// returns 0.00000001

Ответ 16

Вы можете попробовать это, если не хотите использовать округление.

function myFunction(str) {
                    str = str.toString().split('.');
                    var res = str[1].slice(0, 2);
                    document.getElementById("demo").innerHTML = str[0]+'.'+res;
                }
        myFunction(12.234556);
<div id="demo"></div>