Как округлить до 1 десятичного знака в Javascript?


379

Можете ли вы округлить число в javascript до 1 символа после десятичной точки (правильно округлено)?

Я пробовал * 10, раунд, / 10, но он оставляет два десятичных знака в конце int.


9
Math.round(n * 10) / 10работает. Какой у тебя код?
Бен Флеминг,

Ответы:


730

Math.round(num * 10) / 10 работает, вот пример ...

var number = 12.3456789
var rounded = Math.round(number * 10) / 10
// rounded is 12.3

если вы хотите, чтобы он имел одно десятичное место, даже если это будет 0, то добавьте ...

var fixed = rounded.toFixed(1)
// fixed is always to 1 d.p.
// NOTE: .toFixed() returns a string!

// To convert back to number format
parseFloat(number.toFixed(2))
// 12.34
// but that will not retain any trailing zeros

// So, just make sure it is the last step before output,
// and use a number format during calculations!

РЕДАКТИРОВАТЬ: Добавить раунд с функцией точности ...

Используя этот принцип, для справки, вот удобная маленькая круглая функция, которая принимает точность ...

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

... Применение ...

round(12345.6789, 2) // 12345.68
round(12345.6789, 1) // 12345.7

... по умолчанию округляется до ближайшего целого числа (точность 0) ...

round(12345.6789) // 12346

... и может использоваться для округления до ближайших 10 или 100 и т. д. ...

round(12345.6789, -1) // 12350
round(12345.6789, -2) // 12300

... и правильная обработка отрицательных чисел ...

round(-123.45, 1) // -123.4
round(123.45, 1) // 123.5

... и может комбинироваться с toFixed для последовательного форматирования в виде строки ...

round(456.7, 2).toFixed(2) // "456.70"

45
Будьте осторожны при использовании, так .toFixed()как он возвращает строку, когда вы, возможно, хотите число.
Кобби

1
Круто, очевидно, использование parseFloatудалит десятичные дроби, оставленные, .toFixed()если это целое число (нули). Как правило, если вы хотите сделать математику, лучше последовать вашему первому примеру. Если вы хотите отобразить число в вашем пользовательском интерфейсе, используйте .toFixed().
Кобби

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

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

1
Могу ли я добавить ноль, если нет DP?
Ник

102
var number = 123.456;

console.log(number.toFixed(1)); // should round to 123.5

4
Иногда toFixed()возникают глюки - я видел это в браузере Chrome, где я звоню toFixed(), затем преобразую в строку, и он показывает что-то вроде 10.00000000068- странно. Не могу воспроизвести это надежно, хотя.
Хэмиш Грубиджан

Да, я столкнулся с глюками с помощью toFixed () даже с несколькими десятичными знаками. Он округляет дробь 4 до следующего более высокого числа вместо более низкого, если я правильно помню.
Далибор

1
как упомянуто @cobby выше: будьте осторожны с использованием, .toFixed()поскольку оно возвращает, Stringкогда вы, возможно, хотитеNumber
Ricardo

28

Если вы используете, Math.round(5.01)вы получите 5вместо 5.0.

Если вы используете, toFixedвы сталкиваетесь с проблемами округления .

Если вы хотите лучшее из обоих миров, объедините два:

(Math.round(5.01 * 10) / 10).toFixed(1)

Возможно, вы захотите создать функцию для этого:

function roundedToFixed(_float, _digits){
  var rounded = Math.pow(10, _digits);
  return (Math.round(_float * rounded) / rounded).toFixed(_digits);
}

Почему подчеркивания для параметров т.е. (_float, _digits)? Не стесняйтесь просто опубликовать ссылку, где я могу найти ответ для себя. Спасибо
Акула Лазеры


11

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

var rounded = ((num * 10) << 0) * 0.1;

Но, эй, поскольку нет вызовов функций, это быстро. :)

А вот тот, который использует сопоставление строк:

var rounded = (num + '').replace(/(^.*?\d+)(\.\d)?.*/, '$1$2');

Я не рекомендую использовать строковый вариант, просто говорю.


7

Попробуйте с этим:

var original=28.453

// 1.- round "original" to two decimals
var result = Math.round (original * 100) / 100  //returns 28.45

// 2.- round "original" to 1 decimal
var result = Math.round (original * 10) / 10  //returns 28.5

// 3.- round 8.111111 to 3 decimals
var result = Math.round (8.111111 * 1000) / 1000  //returns 8.111

менее сложный и простой в реализации ...

с этим вы можете создать функцию для:

function RoundAndFix (n, d) {
    var m = Math.pow (10, d);
    return Math.round (n * m) / m;
}

РЕДАКТИРОВАТЬ : см. Это Как округлить, используя КРУГЛЫЙ ПОЛОВИНА UP. Режим округления, который большинство из нас учили в начальной школе


Нет: RoundAndFix (1,005, 2).
Noyo

4

x = число, n = десятичные разряды:

function round(x, n) {
    return Math.round(x * Math.pow(10, n)) / Math.pow(10, n)
}

Нет: раунд (1,005, 2).
Noyo

4

Почему не просто

let myNumber = 213.27321;
+myNumber.toFixed(1); // => 213.3
  1. toFixed : возвращает строку, представляющую данное число, используя запись с фиксированной точкой.
  2. Унарный плюс (+) : унарный оператор плюс предшествует своему операнду и вычисляет его операнд, но пытается преобразовать его в число, если это еще не сделано.


3

Чтобы завершить лучший ответ:

var round = function ( number, precision )
{
    precision = precision || 0;
    return parseFloat( parseFloat( number ).toFixed( precision ) );
}

Номер входного параметра может «не» всегда быть числом, в этом случае .toFixed не существует.


3

Версия принятого ответа ES 6:

function round(value, precision) {
    const multiplier = 10 ** (precision || 0);
    return Math.round(value * multiplier) / multiplier;
}

3

Используя метод toPrecision:

var a = 1.2345
a.toPrecision(2)

// result "1.2"

Безусловно, лучший ответ, который я пробовал. Спасибо.
Ste

Но вы должны быть осторожны, потому что 12.345.toPrecision( 2 )есть "12".
Джошуа Пинтер

2

Если ваш метод не работает, пожалуйста, опубликуйте свой код.

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

var value = Math.round(234.567*100)/100

Даст вам 234,56

по аналогии

 var value = Math.round(234.567*10)/10

Даст 234,5

Таким образом, вы можете использовать переменную вместо константы, как указано выше.


1

Маленький угловой фильтр, если кто-то хочет:

angular.module('filters').filter('decimalPlace', function() {
    return function(num, precision) {
        var multiplier = Math.pow(10, precision || 0);
        return Math.round(num * multiplier) / multiplier;
    };
});

используйте если через:

{{model.value| decimalPlace}}
{{model.value| decimalPlace:1}}
{{model.value| decimalPlace:2}}

:)


1

В общем, округление выполняется путем масштабирования: round(num / p) * p

Использование экспоненциальной записи правильно обрабатывает округление чисел + ve. Однако этот метод не может правильно округлить все крайние случаи.

function round(num, precision = 2) {
	var scaled = Math.round(num + "e" + precision);
	return Number(scaled + "e" + -precision);
}

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

console.log( round(-1.005, 2) );  // -1    wrong
console.log( round(-2.175, 2) );  // -2.17 wrong
console.log( round(-5.015, 2) );  // -5.01 wrong

Здесь также есть одна функция, которую я написал для выполнения арифметического округления, вы можете проверить это самостоятельно.

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

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


0

Кажется, что это работает надежно во всем, что я на это бросаю:

function round(val, multiplesOf) {
  var s = 1 / multiplesOf;
  var res = Math.ceil(val*s)/s;
  res = res < val ? res + multiplesOf: res;
  var afterZero = multiplesOf.toString().split(".")[1];
  return parseFloat(res.toFixed(afterZero ? afterZero.length : 0));
}

Он округляется, поэтому вам может потребоваться изменить его в соответствии с вариантом использования. Это должно работать:

console.log(round(10.01, 1)); //outputs 11
console.log(round(10.01, 0.1)); //outputs 10.1

0

Если вы заботитесь о правильном округлении, тогда:

function roundNumericStrings(str , numOfDecPlacesRequired){ 
     var roundFactor = Math.pow(10, numOfDecPlacesRequired);  
     return (Math.round(parseFloat(str)*roundFactor)/roundFactor).toString();  }

В противном случае у вас уже есть ответ от предыдущих сообщений

str.slice(0, -1)

0

Math.round( num * 10) / 10 не работает

Например, 1455581777.8-145558160.4дает вам 1310023617.3999999.

Так что используйте только num.toFixed(1)


0

Я сделал один, который возвращает тип числа, а также помещает десятичные дроби, только если они необходимы (без заполнения 0).

Примеры:

roundWithMaxPrecision(11.234, 2); //11.23
roundWithMaxPrecision(11.234, 1); //11.2
roundWithMaxPrecision(11.234, 4); //11.23
roundWithMaxPrecision(11.234, -1); //10

roundWithMaxPrecision(4.2, 2); //4.2
roundWithMaxPrecision(4.88, 1); //4.9

Код:

function roundWithMaxPrecision (n, precision) {
    return Math.round(n * Math.pow(10, precision)) / Math.pow(10, precision);
}

0

Я нашел способ избежать проблем с точностью:

function badRound (num, precision) {
    const x = 10 ** precision;
    return Math.round(num * x) / x
}
// badRound(1.005, 2) --> 1

function round (num, precision) {
    const x = 10 ** (precision + 1);
    const y = 10 ** precision;
    return Math.round(Math.round(num * x) / 10) / y
}
// round(1.005, 2) --> 1.01

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.