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


Answers

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

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

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

Редактировать: Fiddle

Question

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




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

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



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

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;
}



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

Действительно, toFixed затронут:

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

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

Например, для округления вверх по полу, используя 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. Поэтому мы имеем согласованность, но не «стандартное округление».




    You can try this if you want don't want to use rounding
 function myFunction() {
            var str = 12.234556; 
            str = str.toString().split('.');
            var res = str[1].slice(0, 2);
            document.getElementById("demo").innerHTML = str[0]+'.'+res;
        }
output:12.23

str.toString().split('.') преобразует ваше число с плавающей точкой в ​​строку, а затем разделит его на.

Результирующими переменными будет массив с двумя элементами строкового типа, первым элементом будет 12, а второй элемент - 234556

str[1].slice(0, 2) перерезает вашу вторую (234556) строку на первые два символа, который равен 23

Затем просто конкатенируем первую и результирующую строку через str[0]+'.'+res

Надеюсь, это поможет




/** 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"



Еще одна проблема, о которой нужно знать, заключается в том, что 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"



Links



Tags

javascript javascript