Форматирование числа с точностью до двух десятичных знаков в JavaScript

571

У меня есть эта строка кода, которая округляет мои числа до двух десятичных знаков. Но я получаю такие числа: 10,8, 2,4 и т. Д. Это не мое представление о двух десятичных знаках, так как я могу улучшить следующее?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

Я хочу цифры как 10.80, 2.40 и т. Д. Использование JQuery хорошо для меня.

Abs
источник
1
Ваш код - именно то, что я искал (чтобы уменьшить точность с плавающей точкой до 7 десятичных знаков для меньшего файла JSON). Пропуск Math.pow для скорости val = Math.round (val * 10000000) / 10000000);
Павел
Поскольку в настоящее время общепринятый ответ дает , возможно , неправильный результат для широкого диапазона значений благодаря отягчающим неточностям присущих чисел ( 0.565, 0.575, 1.005), я могу предложить еще раз , глядя на этом ответ , который получает их исправить?
TJ Crowder
Может быть, вы хотите включить библиотеку sprintf для JavaScript stackoverflow.com/questions/610406/…
Thilo
После правильного округления с помощью метода смещения десятичных знаков и округления вы можете использовать этот number.toFixed(x)метод для преобразования его в строку с необходимым количеством нулей. Например, округлить 1.34до 1.3кросс-браузерным методом, затем добавить 1 ноль и преобразовать в строку с помощью 1.3.toFixed(2)(чтобы получить "1.30").
Эдвард

Ответы:

999

Чтобы отформатировать число с использованием записи с фиксированной запятой, вы можете просто использовать метод toFixed :

(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"

Обратите внимание, что toFixed()возвращает строку.

ВАЖНО : обратите внимание, что toFixed не округляет 90% времени, он возвращает округленное значение, но во многих случаях это не работает.

Например:

2.005.toFixed(2) === "2.00"

ОБНОВИТЬ:

В настоящее время вы можете использовать Intl.NumberFormatконструктор. Это часть Спецификации Интернационализации API ECMAScript (ECMA402). Он имеет довольно хорошую поддержку браузера , в том числе даже IE11, и она полностью поддерживается в Node.js .

const formatter = new Intl.NumberFormat('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});

console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"

В качестве альтернативы вы можете использовать toLocaleStringметод, который внутренне будет использовать IntlAPI:

const format = (num, decimals) => num.toLocaleString('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});


console.log(format(2.005)); // "2.01"
console.log(format(1.345)); // "1.35"

Этот API также предоставляет вам широкий выбор вариантов форматирования, например, разделители тысяч, символы валюты и т. Д.

CMS
источник
17
Не работает согласованно во всех браузерах, т.е. (0.09).toFixed(1);дает 0,0 в IE8
ajbeaven
41
исправлено не округляется, вы можете сделать это в первую очередь: (Math.round (0.09)). toFixed (1);
rekans
32
@rekans: это неправильно. Math.Round(0.09)вернется, 0так что это всегда даст 0.0...
Крис
28
В большинстве случаев это плохая идея, в некоторых случаях она преобразует число в строку или число с плавающей точкой.
Эш Блю
80
Согласитесь с @AshBlue здесь ... это безопасно только для форматирования представления значений. Может нарушить код с дальнейшими расчетами. В противном случае Math.round(value*100)/100лучше работает для 2DP.
UpTheCreek
98

Это старая тема, но она по-прежнему занимает первое место в результатах поиска Google, и предлагаемые решения имеют ту же проблему с десятичными числами с плавающей запятой. Вот (очень общая) функция, которую я использую, благодаря MDN :

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}

Как мы видим, мы не получаем эти проблемы:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

Эта универсальность также предоставляет некоторые интересные вещи:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

Теперь, чтобы ответить на вопрос ОП, нужно набрать:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

Или, для более краткой, менее общей функции:

function round2Fixed(value) {
  value = +value;

  if (isNaN(value))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));

  // Shift back
  value = value.toString().split('e');
  return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}

Вы можете позвонить с помощью:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

Различные примеры и тесты (спасибо @ tj-crowder !):

astorije
источник
1
Как не простой способ сделать это? ES6 на помощь?
zero_cool
Спасибо за публикацию полифилла MDN. На связанной MDN-странице больше не заполнен polyfill. Интересно, почему это было удалено ...
Король Холли
43

Я обычно добавляю это в свою личную библиотеку, и после некоторых предложений и использования решения @TIMINeutron, а затем, делая его адаптируемым для десятичной длины, этот вариант подходит лучше всего:

function precise_round(num, decimals) {
   var t = Math.pow(10, decimals);   
   return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

будет работать для зарегистрированных исключений.

Miguel
источник
2
Precision_round (1,275,2) составляет 1,27?
allenhwkim
2
@Imre Измените возвращаемое значение на (Math.round (num * Math.pow (10, десятичные дроби)) / Math.pow (10, десятичные дроби)). ToFixed (2); и у вас больше не будет этой проблемы.
Дкрой
6
где вы объявляете "sign" и "dec", если ваша вторая функция выбрана как есть, разве они не должны быть неопределенными?
Ади Нгом
2
Я добавил обходной путь для метода знака пропуска в IE: gist.github.com/ArminVieweg/28647e735aa6efaba401
Армин,
1
@Armin Ваше исправление также заставляет его работать в Safari. Оригинальная функция не работала в Safari.
Дейв
19

Я не знаю, почему я не могу добавить комментарий к предыдущему ответу (возможно, я безнадежно слеп, не знаю), но я нашел решение, используя ответ @ Miguel:

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

И два комментария (от @bighostkim и @Imre):

  • Проблема с precise_round(1.275,2)невозвращением 1.28
  • Проблема с precise_round(6,2)не возвращением 6,00 (как он хотел).

Мое окончательное решение заключается в следующем:

function precise_round(num,decimals) {
    var sign = num >= 0 ? 1 : -1;
    return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

Как видите, мне пришлось добавить немного «исправления» (это не то, что есть, но поскольку Math.round с потерями - вы можете проверить это на jsfiddle.net - это единственный способ, который я знал, как «исправить» " Это). Это добавляет 0,001 к уже дополненному числу, таким образом, это добавляет 1три 0с справа от десятичного значения. Так что это должно быть безопасно для использования.

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

Вот и все. Используйте это хорошо;)

РЕДАКТИРОВАТЬ: добавлена ​​функциональность для «коррекции» отрицательных чисел.

tfrascaroli
источник
2
«Коррекция» в основном безопасна, но, например, precise_round(1.27499,2)теперь также возвращает 1,28 ... Это не так, Math.roundчто с потерями; способ, которым компьютеры внутренне хранят значения с плавающей запятой. По сути, вы обречены на провал с некоторыми значениями, прежде чем данные даже попадут в вашу функцию :)
Imre
@ Imre, ты абсолютно прав. Вот почему я объясняю, что там делает этот 0,001, на случай, если кто-то захочет сделать его «более точным » или даже удалить его (если у вас есть суперкомпьютер с 2 Мбайт на число с плавающей запятой, что, я думаю, никто здесь не делает ;)
tfrascaroli
1
На самом деле, спецификация языка довольно специфична для использования 64-битных числовых значений, поэтому наличие / использование суперкомпьютера ничего не изменит :)
Imre
для 0,001 вы можете заменить, добавив много нулей в соответствии с длиной десятичных знаков. итак ..
Мигель
15

Один из способов на 100% быть уверенным, что вы получите число с двумя десятичными знаками:

(Math.round(num*100)/100).toFixed(2)

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

(Math.round((num * 1000)/10)/100).toFixed(2)
Жерар де Виссер
источник
6
Это лучший, самый простой способ сделать это. Однако из-за математики с плавающей запятой 1.275 * 100 = 127.49999999999999, что может привести к незначительным ошибкам при округлении. Чтобы исправить это, мы можем умножить на 1000 и разделить на 10, как (1,275 * 1000) / 10 = 127,5. Как следует: var answer = (Math.round((num * 1000)/10)/100).toFixed(2);
Джеймс Гулд
(Math.round ((1.015 * 1000) / 10) / 100). ToFixed (2) по-прежнему дает 1,01, не должно ли быть 1,02?
Gaurav5430
14

toFixed (n) предоставляет n длины после десятичной точки; toPrecision (x) обеспечивает x общую длину.

Используйте этот метод ниже

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

И если вы хотите, чтобы номер был фиксированным, используйте

result = num.toFixed(2);
Сайед Умар Ахмед
источник
это не работает хорошо ... для числа num = 50.2349 вы должны написать в Precision (3), чтобы получить 50.2
Piotr Czyż
это просто пример, который вы можете изменить в соответствии с вашими потребностями @ PiotrCzyż
Сайед Умар Ахмед
5

Я не нашел точного решения этой проблемы, поэтому я создал свое собственное:

function inprecise_round(value, decPlaces) {
  return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}

function precise_round(value, decPlaces){
    var val = value * Math.pow(10, decPlaces);
    var fraction = (Math.round((val-parseInt(val))*10)/10);

    //this line is for consistency with .NET Decimal.Round behavior
    // -342.055 => -342.06
    if(fraction == -0.5) fraction = -0.6;

    val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
    return val;
}

Примеры:

function inprecise_round(value, decPlaces) {
  return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

function precise_round(value, decPlaces) {
  var val = value * Math.pow(10, decPlaces);
  var fraction = (Math.round((val - parseInt(val)) * 10) / 10);

  //this line is for consistency with .NET Decimal.Round behavior
  // -342.055 => -342.06
  if (fraction == -0.5) fraction = -0.6;

  val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
  return val;
}

// This may produce different results depending on the browser environment
console.log("342.055.toFixed(2)         :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10

console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05
console.log("precise_round(342.055, 2)  :", precise_round(342.055, 2));   // 342.06
console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2));  // -342.06

console.log("inprecise_round(0.565, 2)  :", inprecise_round(0.565, 2));   // 0.56
console.log("precise_round(0.565, 2)    :", precise_round(0.565, 2));     // 0.57

Флориан Игнас Эсл
источник
2
Спасибо. Вот немного, чтобы проверить это: jsfiddle.net/lamarant/ySXuF . Я применяю toFixed () к значению до его возвращения, которое добавляет правильное количество нулей к концу возвращаемого значения.
Ламарант
не работает для значения = 0,004990845956707237 и inprecise_round (value, 8) возвращает 0,00499085, но должно возвращать 0,00499084
MERT DOĞAN
3

@heridev и я создали небольшую функцию в jQuery.

Вы можете попробовать следующее:

HTML

<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​

JQuery

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
    $('.two-digits').keyup(function(){
        if($(this).val().indexOf('.')!=-1){         
            if($(this).val().split(".")[1].length > 2){                
                if( isNaN( parseFloat( this.value ) ) ) return;
                this.value = parseFloat(this.value).toFixed(2);
            }  
         }            
         return this; //for chaining
    });
});

ДЕМО ОНЛАЙН:

http://jsfiddle.net/c4Wqn/

vicmaster
источник
1
Я могу оценить этот вклад, хотя я думаю, что добавление DOM-элементов и jQuery в микс кажется вне рамок вопроса.
Крис, май,
Вы не должны слушать событие keyup, так как оно выглядит очень плохо и не активируется, когда вы добавляете что-то с помощью скрипта. Я бы лучше послушал inputсобытие. Это не создает мерцающего эффекта, а также срабатывает при доступе к полю с помощью JS
Le 'nton
3

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

Когда компьютер хранит 1,275 как значение с плавающей запятой, он на самом деле не будет помнить, было ли это 1,275 или 1,27499999999999993 или даже 1,27500000000000002. Эти значения должны давать разные результаты после округления до двух десятичных знаков, но они не будут, поскольку для компьютера они выглядят точно так же после сохранения в виде значений с плавающей запятой, и нет никакого способа восстановить потерянные данные. Любые дальнейшие вычисления только накапливают такую ​​неточность.

Так что, если точность имеет значение, вы должны избегать значений с плавающей точкой с самого начала. Самые простые варианты

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

Например, при использовании целых чисел для хранения числа сотых функция поиска действительного значения довольно проста:

function descale(num, decimals) {
    var hasMinus = num < 0;
    var numString = Math.abs(num).toString();
    var precedingZeroes = '';
    for (var i = numString.length; i <= decimals; i++) {
        precedingZeroes += '0';
    }
    numString = precedingZeroes + numString;
    return (hasMinus ? '-' : '') 
        + numString.substr(0, numString.length-decimals) 
        + '.' 
        + numString.substr(numString.length-decimals);
}

alert(descale(127, 2));

Со строками вам понадобится округление, но оно все еще управляемо:

function precise_round(num, decimals) {
    var parts = num.split('.');
    var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
    var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
    var decimalPart = parts.length > 1 ? parts[1] : '';
    if (decimalPart.length > decimals) {
        var roundOffNumber = decimalPart.charAt(decimals);
        decimalPart = decimalPart.substr(0, decimals);
        if ('56789'.indexOf(roundOffNumber) > -1) {
            var numbers = integralPart + decimalPart;
            var i = numbers.length;
            var trailingZeroes = '';
            var justOneAndTrailingZeroes = true;
            do {
                i--;
                var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
                if (roundedNumber === '0') {
                    trailingZeroes += '0';
                } else {
                    numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
                    justOneAndTrailingZeroes = false;
                    break;
                }
            } while (i > 0);
            if (justOneAndTrailingZeroes) {
                numbers = '1' + trailingZeroes;
            }
            integralPart = numbers.substr(0, numbers.length - decimals);
            decimalPart = numbers.substr(numbers.length - decimals);
        }
    } else {
        for (var i = decimalPart.length; i < decimals; i++) {
            decimalPart += '0';
        }
    }
    return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

Обратите внимание, что эта функция округляет до ближайшего, связывает от нуля , в то время как IEEE 754 рекомендует округлять до ближайшего, даже в качестве поведения по умолчанию для операций с плавающей запятой. Такие модификации оставлены в качестве упражнения для читателя :)

Имре
источник
3

Вот простой

function roundFloat(num,dec){
    var d = 1;
    for (var i=0; i<dec; i++){
        d += "0";
    }
    return Math.round(num * d) / d;
}

Используйте как alert(roundFloat(1.79209243929,4));

Jsfiddle

ow3n
источник
2

Округлите десятичное значение, затем используйте toFixed(x)ожидаемые цифры.

function parseDecimalRoundAndFixed(num,dec){
  var d =  Math.pow(10,dec);
  return (Math.round(num * d) / d).toFixed(dec);
}

Вызов

parseDecimalRoundAndFixed (10.800243929,4) => 10.80 parseDecimalRoundAndFixed (10.807243929,2) => 10.81

HATCHA
источник
2

Округлить вниз

function round_down(value, decPlaces) {
    return Math.floor(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Округлять

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Ближайший тур

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Объединенные https://stackoverflow.com/a/7641824/1889449 и https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm Спасибо им.

MERT DOĞAN
источник
2

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some +ve edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

// testing some -ve edge cases
console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct

Амр Али
источник
2

Вот мое 1-строчное решение: Number((yourNumericValueHere).toFixed(2));

Вот что происходит:

1) Сначала вы применяете .toFixed(2)число, к которому хотите округлить десятичные знаки. Обратите внимание, что это преобразует значение в строку из числа. Так что, если вы используете Typescript, он выдаст такую ​​ошибку:

"Тип 'строка' не может быть назначен типу 'число'"

2) Чтобы вернуть числовое значение или преобразовать строку в числовое значение, просто примените Number()функцию к так называемому «строковому» значению.

Для уточнения посмотрите на пример ниже:

ПРИМЕР: у меня есть количество, которое имеет до 5 цифр в десятичных разрядах, и я хотел бы сократить его до 2 десятичных разрядов. Я делаю это так:

var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);

Devner
источник
1

Поместите следующее в какую-то глобальную область:

Number.prototype.getDecimals = function ( decDigCount ) {
   return this.toFixed(decDigCount);
}

а затем попробуйте :

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

Обновить

Обратите внимание, что toFixed()может работать только для числа десятичных знаков между, 0-20т. Е. a.getDecimals(25)Может генерировать ошибку JavaScript, поэтому для удобства вы можете добавить некоторые дополнительные проверки, т. Е.

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}
Камран Ахмед
источник
1
Number(((Math.random() * 100) + 1).toFixed(2))

это вернет случайное число от 1 до 100, округленное до 2 десятичных знаков.

Джонатан Раллс
источник
1

Используя этот ответ по ссылке: https://stackoverflow.com/a/21029698/454827

Я строю функцию, чтобы получить динамические числа десятичных дробей:

function toDec(num, dec)
{
        if(typeof dec=='undefined' || dec<0)
                dec = 2;

        var tmp = dec + 1;
        for(var i=1; i<=tmp; i++)
                num = num * 10;

        num = num / 10;
        num = Math.round(num);
        for(var i=1; i<=dec; i++)
                num = num / 10;

        num = num.toFixed(dec);

        return num;
}

Вот рабочий пример: https://jsfiddle.net/wpxLduLc/

ZiTAL
источник
1

parse = function (data) {
       data = Math.round(data*Math.pow(10,2))/Math.pow(10,2);
       if (data != null) {
            var lastone = data.toString().split('').pop();
            if (lastone != '.') {
                 data = parseFloat(data);
            }
       }
       return data;
  };

$('#result').html(parse(200)); // output 200
$('#result1').html(parse(200.1)); // output 200.1
$('#result2').html(parse(200.10)); // output 200.1
$('#result3').html(parse(200.109)); // output 200.11
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="result"></div>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>

Вишну Т Асок
источник
1

В этих примерах вы все равно получите ошибку при попытке округлить число 1.005, решение состоит в том, чтобы использовать библиотеку, такую ​​как Math.js, или эту функцию:

function round(value: number, decimals: number) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
Дэвид Вебстер
источник
1

Я получил некоторые идеи из этого поста несколько месяцев назад, но ни один из ответов здесь, ни ответы из других постов / блогов не могли обработать все сценарии (например, отрицательные числа и некоторые "счастливые числа", найденные нашим тестировщиком). В итоге наш тестер не обнаружил никаких проблем с этим методом ниже. Вставка фрагмента моего кода:

fixPrecision: function (value) {
    var me = this,
        nan = isNaN(value),
        precision = me.decimalPrecision;

    if (nan || !value) {
        return nan ? '' : value;
    } else if (!me.allowDecimals || precision <= 0) {
        precision = 0;
    }

    //[1]
    //return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
    precision = precision || 0;
    var negMultiplier = value < 0 ? -1 : 1;

    //[2]
    var numWithExp = parseFloat(value + "e" + precision);
    var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
    return parseFloat(roundedNum.toFixed(precision));
},

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

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).
Remondo
источник
0

Я исправил проблему модификатором. Поддержка 2 десятичных только.

$(function(){
  //input number only.
  convertNumberFloatZero(22); // output : 22.00
  convertNumberFloatZero(22.5); // output : 22.50
  convertNumberFloatZero(22.55); // output : 22.55
  convertNumberFloatZero(22.556); // output : 22.56
  convertNumberFloatZero(22.555); // output : 22.55
  convertNumberFloatZero(22.5541); // output : 22.54
  convertNumberFloatZero(22222.5541); // output : 22,222.54

  function convertNumberFloatZero(number){
	if(!$.isNumeric(number)){
		return 'NaN';
	}
	var numberFloat = number.toFixed(3);
	var splitNumber = numberFloat.split(".");
	var cNumberFloat = number.toFixed(2);
	var cNsplitNumber = cNumberFloat.split(".");
	var lastChar = splitNumber[1].substr(splitNumber[1].length - 1);
	if(lastChar > 0 && lastChar < 5){
		cNsplitNumber[1]--;
	}
	return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

bamossza
источник
0
(Math.round((10.2)*100)/100).toFixed(2)

Это должно дать: 10.20

(Math.round((.05)*100)/100).toFixed(2)

Это должно дать: 0.05

(Math.round((4.04)*100)/100).toFixed(2)

Это должно дать: 4.04

и т.п.

Энтони Руффино
источник
0

/*Due to all told stuff. You may do 2 things for different purposes:
When showing/printing stuff use this in your alert/innerHtml= contents:
YourRebelNumber.toFixed(2)*/

var aNumber=9242.16;
var YourRebelNumber=aNumber-9000;
alert(YourRebelNumber);
alert(YourRebelNumber.toFixed(2));

/*and when comparing use:
Number(YourRebelNumber.toFixed(2))*/

if(YourRebelNumber==242.16)alert("Not Rounded");
if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded");

/*Number will behave as you want in that moment. After that, it'll return to its defiance.
*/

Кристиан Лирбаг
источник
0

Это очень просто и работает так же, как и любой другой:

function parseNumber(val, decimalPlaces) {
    if (decimalPlaces == null) decimalPlaces = 0
    var ret = Number(val).toFixed(decimalPlaces)
    return Number(ret)
}

Так как toFixed () может вызываться только для чисел и, к сожалению, возвращает строку, это делает весь анализ для вас в обоих направлениях. Вы можете передать строку или число, и вы получите номер обратно каждый раз! Вызов parseNumber (1.49) даст вам 1, а parseNumber (1.49,2) даст вам 1,50. Так же, как лучшие из них!

Аарон Дэйк
источник
0

Вы также можете использовать .toPrecision()метод и некоторый пользовательский код и всегда округлять до n-го десятичного знака независимо от длины части int.

function glbfrmt (number, decimals, seperator) {
    return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

Вы также можете сделать его плагином для лучшего использования.

leo_lo
источник
-1

Просто как это.

var rounded_value=Math.round(value * 100) / 100;
Гихан Гамаж
источник
1
Неправильно. Попробуйте 1.015
Марко Марсала
-2

Я нашел очень простой способ, который решил эту проблему для меня и может быть использован или адаптирован:

td[row].innerHTML = price.toPrecision(price.toFixed(decimals).length

источник
-4

100% работает !!! Попробуй это

<html>
     <head>
      <script>
      function replacePonto(){
        var input = document.getElementById('qtd');
        var ponto = input.value.split('.').length;
        var slash = input.value.split('-').length;
        if (ponto > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        if(slash > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        input.value=input.value.replace(/[^0-9.-]/,'');

        if (ponto ==2)
	input.value=input.value.substr(0,(input.value.indexOf('.')+3));

if(input.value == '.')
	input.value = "";
              }
      </script>
      </head>
      <body>
         <input type="text" id="qtd" maxlength="10" style="width:140px" onkeyup="return replacePonto()">
      </body>
    </html>

ХОНАС МАГАЛЬХА ДОС САНТОС
источник
Добро пожаловать в ТАК. Пожалуйста, прочитайте эту инструкцию и следуйте инструкциям, чтобы ответить.
thewaywewere