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

197

Предположим, у меня есть значение 15,7784514, я хочу отобразить его 15,77 без округления.

var num = parseFloat(15.7784514);
document.write(num.toFixed(1)+"<br />");
document.write(num.toFixed(2)+"<br />");
document.write(num.toFixed(3)+"<br />");
document.write(num.toFixed(10));

Результаты в -

15.8
15.78
15.778
15.7784514000 

Как мне отобразить 15.77?

tempid
источник
3
Я испытываю желание спросить, почему вы не хотите округления? Кажется неправильным, независимо от того, где ...
Камило Мартин
40
Это полезно при отображении валюты.
Ричард Е.
@ mik01aj - при отображении валюты чаще используется усечение вычисленных значений, а не их округление. Например, большинство налоговых форм в США усечены, а не округлены в расчете на дробные центы. В этом случае усеченное значение является правильным значением.
Стивен Бикс
4
@CamiloMartin существует огромная разница между задолженностью 1,49 миллиарда долларов и 1,0 миллиарда долларов.
Брода Ноэль
3
Существует также огромная разница между 1,49 млрд. И 1,50 млрд. Долларов. Это 100 миллионов долларов.
Лига

Ответы:

228

Преобразуйте число в строку, сопоставьте число с точностью до второго десятичного знака:

function calc(theform) {
    var num = theform.original.value, rounded = theform.rounded
    var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
    rounded.value = with2Decimals
}
<form onsubmit="return calc(this)">
Original number: <input name="original" type="text" onkeyup="calc(form)" onchange="calc(form)" />
<br />"Rounded" number: <input name="rounded" type="text" placeholder="readonly" readonly>
</form>

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

гумбо
источник
22
+1 Это должно решить проблему округления. Я бы до сих пор выводит результат выше использование toFixed, хотя, так: (Math.floor(value * 100) / 100).toFixed(2). Как вы, вероятно, знаете, со значениями с плавающей запятой могут происходить странные прецизионные вещи (и на другой стороне спектра, если число оказывается 15, звучит так, как хочет ОП 15.00).
TJ Crowder
1
хе-хе, или если вы объедините оба:Number((15.7784514000*100).toString().match(/^\d+/)/100);
skobaljic
27
Math.floor (значение * 100) / 100 не будет работать, если значение серьезно = 4.27, попробуйте.
Темный Бегемот
3
@DarkHippo Это потому, что 4.27 на самом деле 4.26999999999, Math.round, как правило, лучшее решение, хотя и не ответ на первоначальный вопрос. Реально, учитывая, что вывод представляет собой строку, это должно быть сделано с использованием строковых манипуляций вместо численного решения со всеми ошибками с плавающей запятой.
BJury
3
... это не звучит правильно. Конвертация между типами при любых обстоятельствах кажется обходной и небезопасной. Если действительно продвинутый программист не станет утверждать, что «все типы - это просто потоки» или что-то в этом роде.
JackHasaKeyboard
66

Обновление 5 ноября 2016

Новый ответ, всегда точный

function toFixed(num, fixed) {
    var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
    return num.toString().match(re)[0];
}

Поскольку математика с плавающей запятой в javascript всегда будет иметь крайние значения, предыдущее решение будет в большинстве случаев точным, что недостаточно. Есть некоторые решения этого , как num.toPrecision, BigDecimal.js и accounting.js . Тем не менее, я считаю, что простой анализ строки будет самым простым и всегда точным.

Основываясь на обновленном хорошо написанном регулярном выражении из принятого ответа @Gumbo, эта новая функция toFixed всегда будет работать как положено.


Старый ответ, не всегда точный.

Сверните свою собственную функцию toFixed:

function toFixed(num, fixed) {
    fixed = fixed || 0;
    fixed = Math.pow(10, fixed);
    return Math.floor(num * fixed) / fixed;
}
Guya
источник
7
Исправлено (4,56, 2) = 4,55
крик
2
У многих из этих ответов есть умножение внутри функции Math.floor (). Это не удастся для некоторых чисел! Арифметика с плавающей точкой не является точной, и вам нужно использовать разные методы.
Нико Вестердейл
1
function toFixedCustom (num, fixed) {var re = new RegExp ('^ -? \\ d + (?: \. \\ d {0,' + (fixed || -1) + '})?'); if (num.toString (). match (re)) {return num.toString (). match (re) [0]; }}
Райан Августин
1
Обновленный ответ потерпит неудачу для числа, большого или достаточно малого, чтобы javascript представлял в научной нотации. toFixed(0.0000000052, 2)дает «5,2». Это можно исправить, используя return num.toFixed(fixed+1).match(re)[0];Уведомление о том, что я использую toFixed с одним десятичным знаком над целью, чтобы избежать округления, а затем запускаю ваше регулярное выражение
Netherdan
34

Вместо этого я решил написать это, чтобы вручную удалить остаток со строками, чтобы мне не приходилось иметь дело с математическими проблемами, которые идут с числами:

num = num.toString(); //If it's not already a String
num = num.slice(0, (num.indexOf("."))+3); //With 3 exposing the hundredths place
Number(num); //If you need it back as a Number

Это даст вам «15,77» с числом = 15,7784514;

ベ ン ノ ス ケ
источник
5
Если вы не используете десятичную дробь, вы можете добавить условное выражение, если вы встретите целые числа. Вот так: num = num.toString (); if (num.indexOf (".")> 0) {num = num.slice (0, (num.indexOf (".")) + 3)}; Номер (число);
ケ ン ノ ス ケ
1
хорошо, если в нем есть десятичные дроби, но если это целое число, оно потерпит неудачу
Руслан Лопес
Если Num является 0.00000052, то это будет неправильно получать 5.2e
Взант
1
@Vasanth Если число равно 0,00000052, возвращается «0,00». Может быть, ответ был отредактирован с тех пор
Drenai
Да, это не удается в крайних случаях
VPaul
18

Октябрь 2017

Общее решение - усечь (без округления) число до n-й десятичной цифры и преобразовать его в строку с ровно n десятичными цифрами для любого n≥0.

function toFixedTrunc(x, n) {
  const v = (typeof x === 'string' ? x : x.toString()).split('.');
  if (n <= 0) return v[0];
  let f = v[1] || '';
  if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
  while (f.length < n) f += '0';
  return `${v[0]}.${f}`
}

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

Вот несколько тестов для n = 2 (включая тест, запрошенный OP):

0           => 0.00
0.01        => 0.01
0.5839      => 0.58
0.999       => 0.99
1.01        => 1.01
2           => 2.00
2.551       => 2.55
2.99999     => 2.99
4.27        => 4.27
15.7784514  => 15.77
123.5999    => 123.59
0.000000199 => 1.99 *

* Как упомянуто в примечании, это связано с неявным преобразованием javascript в экспоненциальное для "1.99e-7" и для некоторых других значений n:

15.001097   => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
SC1000
источник
2
toFixedTrunc(0.000000199, 2) // 1.99
Магеррамов
1
@ShamkhalMaharramov: если вы откроете консоль разработки и введете 0.000000199, что вы получите? Вы получаете 1.99e-7. Кроме того, если вы введете 0.000000199.toString (), что вы получите? Вы получаете «1,99e-7» Таким образом, когда вы передаете 0,000000199 функции, она в конечном итоге работает с «1,99e-7», а не с «0,000000199» и «правильно» возвращает «1,99». См ecma-international.org/ecma-262/6.0/...
SC1000
13

parseInt быстрее, чем Math.floor

function floorFigure(figure, decimals){
    if (!decimals) decimals = 2;
    var d = Math.pow(10,decimals);
    return (parseInt(figure*d)/d).toFixed(decimals);
};

floorFigure(123.5999)    =>   "123.59"
floorFigure(123.5999, 3) =>   "123.599"
Мартин Вармус
источник
2
это терпит неудачу с 1234567.89
Руслан Лопес
Не могли бы вы разработать Лопес?
zardilior
3
floorFigure (4.56, 2) = 4.55
cryss
7
num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)

Это вернется 19,66

Алекс Пэн
источник
5
(4.9999) .toFixed (3) .slice (0, -1) возвращает 5,00, ожидаемый результат - 4,99.
Бруно Лемос
1
Я рекомендую использовать что-то вроде .toFixed (6) .slice (0, -4).
Бруно Лемос
это прекрасно, в моем случае все хорошо. например, если я хочу иметь только одно десятичное число, используйте num.toFixed (2) .slice (0, -1) (если num имеет 1,2356, он вернет 1,2)
Эстебан Перес
7

Просто сделай это

number = parseInt(number * 100)/100;
Имран Поллоб
источник
4
parseInt (8,2 * 100) = 819
VPaul
5

Эти решения действительно работают, но мне кажутся излишне сложными. Мне лично нравится использовать оператор модуля для получения остатка от операции деления и удаления этого. Предполагая, что число = 15,7784514:

num-=num%.01;

Это эквивалентно высказыванию num = num - (num% .01).

jtrick
источник
Это интересно, Nijkokun, спасибо, что указал на это. Я никогда не сталкивался с проблемами, используя эту технику, но ясно, что я должен поближе взглянуть на подобные случаи. В качестве альтернативы вы можете использовать ((num * = 100) - (num% 1)) / 100, что решает эту проблему. Приоритетом в моем случае является скорость выполнения из-за объема вычислений, к которым я применяю это, и это самый быстрый способ достижения этого, который я нашел.
Jtrick
1
Задача состояла в том, чтобы избежать поиска и преобразования объектов и функций, необходимых в других предлагаемых решениях. Спасибо за ответ!
Jtrick
1
также терпит неудачу с минусами как -5
Руслан Лопес
Я также заинтересован в быстром округлении, как бы вы заставили этот код делать 1 десятичный знак?
thednp
5

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

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

function Dec2(num) {
  num = String(num);
  if(num.indexOf('.') !== -1) {
    var numarr = num.split(".");
    if (numarr.length == 1) {
      return Number(num);
    }
    else {
      return Number(numarr[0]+"."+numarr[1].charAt(0)+numarr[1].charAt(1));
    }
  }
  else {
    return Number(num);
  }  
}

Dec2(99); // 99
Dec2(99.9999999); // 99.99
Dec2(99.35154); // 99.35
Dec2(99.8); // 99.8
Dec2(10265.985475); // 10265.98
Дэвид Д
источник
Dec2 (99) должен вернуться 99.00
VPaul
5

Моя версия для положительных чисел:

function toFixed_norounding(n,p)
{
    var result = n.toFixed(p);
    return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p);
}

Быстро, красиво, очевидно. (версия для положительных чисел)

Альфа и Омега
источник
требуется округление для значений с плавающей запятой (например, денег), только с 1 десятичным знаком. Вышеупомянутая функция должна быть «ответом» этой темы, она превосходна, работает как шарм. Приветствия автору и спасибо. :)))
Адриан
Не удалось получить отрицательное значение. -0.7752, Проверьте это toFixed_norounding(-0.7752,2)возвращается -0.78вместо-0.77
Линг Лоэнг
4

Следующий код работает очень хорошо для меня:

num.toString().match(/.\*\\..{0,2}|.\*/)[0];
Missiria
источник
Я добавлю дополнительный знак минус, чтобы сделать его идеальным -?;)
Руслан Лопес
3

Я исправил, используя следующий простой способ:

var num = 15.7784514;
Math.floor(num*100)/100;

Результаты будут 15.77

OMS
источник
Он не работает с отрицательными значениями: -15.7784514возвращается-15.78
Clément Baconnier
3

Просто обрежьте цифры:

function truncDigits(inputNumber, digits) {
  const fact = 10 ** digits;
  return Math.floor(inputNumber * fact) / fact;
}
Араль Рока
источник
3

Еще одно однострочное решение:

number = Math.trunc(number*100)/100

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

number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)

где цифры - это количество десятичных цифр для хранения.

Посмотрите спецификации Math.trunc для деталей и совместимости браузера.

remidej
источник
1
Это лучший ответ, если вам не нужно поддерживать IE11.
TJ.
2

Вот, пожалуйста. Ответ, который показывает еще один способ решения проблемы:

// For the sake of simplicity, here is a complete function:
function truncate(numToBeTruncated, numOfDecimals) {
    var theNumber = numToBeTruncated.toString();
    var pointIndex = theNumber.indexOf('.');
    return +(theNumber.slice(0, pointIndex > -1 ? ++numOfDecimals + pointIndex : undefined));
}

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

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

Якуб Барчик
источник
1
Мне нравится простота этого подхода, и я чувствую, что все решения, которые избегают использования математики, являются более подходящими для решения этой проблемы. Таким образом, использование slice () и т. Д. - правильный путь вперед. Единственное преимущество моего метода заключается в том, что он обрабатывает переданные числа, которые являются строками [заключенными в кавычки [одинарный / двойной]]. По какой-то причине вышеприведенная функция вызвала ошибку в FF, когда я это сделал: console.log ('truncate ("0.85156", 2)', truncate ("0.85156", 2));
Чарльз Робертсон
2

обрезать без нулей

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

или

function toTrunc(value,n){
    x=(value.toString()+".0").split(".");
    return parseFloat(x[0]+"."+x[1].substr(0,n));
}

тест:

toTrunc(17.4532,2)  //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1)   //1.4
toTrunc(.4,2)       //0.4

усечь с нулями

function toTruncFixed(value,n){
    return toTrunc(value,n).toFixed(n);
}

тест:

toTrunc(17.4532,2)  //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1)   //1.4
toTrunc(.4,2)       //0.40
ShAkKiR
источник
2

Это хорошо сработало для меня. Я надеюсь, что это исправит и ваши проблемы.

function toFixedNumber(number) {
    const spitedValues = String(number.toLocaleString()).split('.');
    let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
    decimalValue = decimalValue.concat('00').substr(0,2);

    return '$'+spitedValues[0] + '.' + decimalValue;
}

// 5.56789      ---->  $5.56
// 0.342        ---->  $0.34
// -10.3484534  ---->  $-10.34 
// 600          ---->  $600.00

function convertNumber(){
  var result = toFixedNumber(document.getElementById("valueText").value);
  document.getElementById("resultText").value = result;
}


function toFixedNumber(number) {
        const spitedValues = String(number.toLocaleString()).split('.');
        let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
        decimalValue = decimalValue.concat('00').substr(0,2);

        return '$'+spitedValues[0] + '.' + decimalValue;
}
<div>
  <input type="text" id="valueText" placeholder="Input value here..">
  <br>
  <button onclick="convertNumber()" >Convert</button>
  <br><hr>
  <input type="text" id="resultText" placeholder="result" readonly="true">
</div>

Sandaru
источник
2

Простой способ сделать это следующий, но необходимо убедиться, что значение параметра приведено в виде строки.

function truncate(amountAsString, decimals = 2){
  var dotIndex = amountAsString.indexOf('.');
  var toTruncate = dotIndex !== -1  && ( amountAsString.length > dotIndex + decimals + 1);
  var approach = Math.pow(10, decimals);
  var amountToTruncate = toTruncate ? amountAsString.slice(0, dotIndex + decimals +1) : amountAsString;  
  return toTruncate
    ?  Math.floor(parseFloat(amountToTruncate) * approach ) / approach
    :  parseFloat(amountAsString);

}

console.log(truncate("7.99999")); //OUTPUT ==> 7.99
console.log(truncate("7.99999", 3)); //OUTPUT ==> 7.999
console.log(truncate("12.799999999999999")); //OUTPUT ==> 7.99
Фелипе Санта
источник
2

function formatLimitDecimals(value, decimals) {
  value = value.toString().split('.')

  if (value.length === 2) {
    return Number([value[0], value[1].slice(0, decimals)].join('.'))
  } else {
    return Number(value[0]);
  }
}

console.log(formatLimitDecimals(4.156, 2)); // 4.15
console.log(formatLimitDecimals(4.156, 8)); // 4.156
console.log(formatLimitDecimals(4.156, 0)); // 4

Рубен Моралес Феликс
источник
1

Я имел обыкновение (num-0.05).toFixed(1)получать второй десятичный этаж.

王景飞
источник
1

Мое решение в машинописи (может быть легко перенесено на JS):

/**
 * Returns the price with correct precision as a string
 *
 * @param   price The price in decimal to be formatted.
 * @param   decimalPlaces The number of decimal places to use
 * @return  string The price in Decimal formatting.
 */
type toDecimal = (price: number, decimalPlaces?: number) => string;
const toDecimalOdds: toDecimal = (
  price: number,
  decimalPlaces: number = 2,
): string => {
  const priceString: string = price.toString();
  const pointIndex: number = priceString.indexOf('.');

  // Return the integer part if decimalPlaces is 0
  if (decimalPlaces === 0) {
    return priceString.substr(0, pointIndex);
  }

  // Return value with 0s appended after decimal if the price is an integer
  if (pointIndex === -1) {
    const padZeroString: string = '0'.repeat(decimalPlaces);

    return `${priceString}.${padZeroString}`;
  }

  // If numbers after decimal are less than decimalPlaces, append with 0s
  const padZeroLen: number = priceString.length - pointIndex - 1;
  if (padZeroLen > 0 && padZeroLen < decimalPlaces) {
    const padZeroString: string = '0'.repeat(padZeroLen);

    return `${priceString}${padZeroString}`;
  }

  return priceString.substr(0, pointIndex + decimalPlaces + 1);
};

Тестовые случаи:

  expect(filters.toDecimalOdds(3.14159)).toBe('3.14');
  expect(filters.toDecimalOdds(3.14159, 2)).toBe('3.14');
  expect(filters.toDecimalOdds(3.14159, 0)).toBe('3');
  expect(filters.toDecimalOdds(3.14159, 10)).toBe('3.1415900000');
  expect(filters.toDecimalOdds(8.2)).toBe('8.20');

Какие-нибудь улучшения?

VPaul
источник
0

Прокрутите свою собственную toFixedфункцию: для положительных значений Math.floorработает нормально.

function toFixed(num, fixed) {
    fixed = fixed || 0;
    fixed = Math.pow(10, fixed);
    return Math.floor(num * fixed) / fixed;
}

Для отрицательных значений Math.floorесть округление значений. Таким образом, вы можете использовать Math.ceilвместо этого.

Пример,

Math.ceil(-15.778665 * 10000) / 10000 = -15.7786
Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong.
Бупати Сактивел
источник
5
У многих из этих ответов есть умножение внутри функции Math.floor (). Это не удастся для некоторых чисел! Арифметика с плавающей точкой не является точной, и вам нужно использовать разные методы.
Нико Вестердейл
0

Второе решение Gumbo с регулярным выражением работает, но медленно из-за регулярного выражения. Первое решение Gumbo дает сбой в определенных ситуациях из-за неточности в числах с плавающей запятой. Посмотрите JSFiddle для демонстрации и эталона. Второе решение занимает около 1636 наносекунд на вызов в моей нынешней системе, процессор Intel Core i5-2500 с тактовой частотой 3,30 ГГц.

Решение, которое я написал, включает добавление небольшой компенсации, чтобы позаботиться о неточности с плавающей запятой. Это в основном мгновенно, то есть порядка наносекунд. Я набрал 2 наносекунды за звонок, но таймеры JavaScript не очень точны и не точны. Вот JS Fiddle и код.

function toFixedWithoutRounding (value, precision)
{
    var factorError = Math.pow(10, 14);
    var factorTruncate = Math.pow(10, 14 - precision);
    var factorDecimal = Math.pow(10, precision);
    return Math.floor(Math.floor(value * factorError + 1) / factorTruncate) / factorDecimal;
}

var values = [1.1299999999, 1.13, 1.139999999, 1.14, 1.14000000001, 1.13 * 100];

for (var i = 0; i < values.length; i++)
{
    var value = values[i];
    console.log(value + " --> " + toFixedWithoutRounding(value, 2));
}

for (var i = 0; i < values.length; i++)
{
    var value = values[i];
    console.log(value + " --> " + toFixedWithoutRounding(value, 4));
}

console.log("type of result is " + typeof toFixedWithoutRounding(1.13 * 100 / 100, 2));

// Benchmark
var value = 1.13 * 100;
var startTime = new Date();
var numRun = 1000000;
var nanosecondsPerMilliseconds = 1000000;

for (var run = 0; run < numRun; run++)
    toFixedWithoutRounding(value, 2);

var endTime = new Date();
var timeDiffNs = nanosecondsPerMilliseconds * (endTime - startTime);
var timePerCallNs = timeDiffNs / numRun;
console.log("Time per call (nanoseconds): " + timePerCallNs);
Даниэль Барбалас
источник
0

Опираясь на ответ Дэвида Д.

function NumberFormat(num,n) {
  var num = (arguments[0] != null) ? arguments[0] : 0;
  var n = (arguments[1] != null) ? arguments[1] : 2;
  if(num > 0){
    num = String(num);
    if(num.indexOf('.') !== -1) {
      var numarr = num.split(".");
      if (numarr.length > 1) {
        if(n > 0){
          var temp = numarr[0] + ".";
          for(var i = 0; i < n; i++){
            if(i < numarr[1].length){
              temp += numarr[1].charAt(i);
            }
          }
          num = Number(temp);
        }
      }
    }
  }
  return Number(num);
}

console.log('NumberFormat(123.85,2)',NumberFormat(123.85,2));
console.log('NumberFormat(123.851,2)',NumberFormat(123.851,2));
console.log('NumberFormat(0.85,2)',NumberFormat(0.85,2));
console.log('NumberFormat(0.851,2)',NumberFormat(0.851,2));
console.log('NumberFormat(0.85156,2)',NumberFormat(0.85156,2));
console.log('NumberFormat(0.85156,4)',NumberFormat(0.85156,4));
console.log('NumberFormat(0.85156,8)',NumberFormat(0.85156,8));
console.log('NumberFormat(".85156",2)',NumberFormat(".85156",2));
console.log('NumberFormat("0.85156",2)',NumberFormat("0.85156",2));
console.log('NumberFormat("1005.85156",2)',NumberFormat("1005.85156",2));
console.log('NumberFormat("0",2)',NumberFormat("0",2));
console.log('NumberFormat("",2)',NumberFormat("",2));
console.log('NumberFormat(85156,8)',NumberFormat(85156,8));
console.log('NumberFormat("85156",2)',NumberFormat("85156",2));
console.log('NumberFormat("85156.",2)',NumberFormat("85156.",2));

// NumberFormat(123.85,2) 123.85
// NumberFormat(123.851,2) 123.85
// NumberFormat(0.85,2) 0.85
// NumberFormat(0.851,2) 0.85
// NumberFormat(0.85156,2) 0.85
// NumberFormat(0.85156,4) 0.8515
// NumberFormat(0.85156,8) 0.85156
// NumberFormat(".85156",2) 0.85
// NumberFormat("0.85156",2) 0.85
// NumberFormat("1005.85156",2) 1005.85
// NumberFormat("0",2) 0
// NumberFormat("",2) 0
// NumberFormat(85156,8) 85156
// NumberFormat("85156",2) 85156
// NumberFormat("85156.",2) 85156
Чарльз Робертсон
источник
0

Надежнее получить две плавающие точки без округления.

Ссылка Ответ

var number = 10.5859;
var fixed2FloatPoints = parseInt(number * 100) / 100;
console.log(fixed2FloatPoints);

Спасибо !

Джейди Мор
источник
0

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

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
король нео
источник
0

Вот что сделал со строкой

export function withoutRange(number) {
  const str = String(number);
  const dotPosition = str.indexOf('.');
  if (dotPosition > 0) {
    const length = str.substring().length;
    const end = length > 3 ? 3 : length;
    return str.substring(0, dotPosition + end);
  }
  return str;
}
Кишан Вагела
источник
0

Все эти ответы кажутся немного сложными. Я бы просто вычел 0.5 из вашего числа и использовал бы toFixed ().

Шон Мэйс
источник
Вы имели в виду 0,005?
Луан Нгуен
0

Наиболее эффективное решение (для 2-х дробных цифр) состоит в том, чтобы вычесть 0,005 перед вызовом toFixed()

function toFixed2( num ) { return (num-0.005).toFixed(2) }

Отрицательные числа тоже будут округлены (от нуля). ОП ничего не сказал об отрицательных числах.

Wiimm
источник
0

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

Это моя альтернатива toFixed, которая не округляет числа, просто усекает их или добавляет нули в соответствии с заданной точностью. Для очень длинных чисел используется встроенное округление JS, когда точность слишком велика. Функция работает для всех проблемных чисел, которые я нашел в стеке.

function toFixedFixed(value, precision = 0) {
    let stringValue = isNaN(+value) ? '0' : String(+value);

    if (stringValue.indexOf('e') > -1 || stringValue === 'Infinity' || stringValue === '-Infinity') {
        throw new Error('To large number to be processed');
    }

    let [ beforePoint, afterPoint ] = stringValue.indexOf('.') > -1 ? stringValue.split('.') : [ stringValue, ''];

    // Force automatic rounding for some long real numbers that ends with 99X, by converting it to string, cutting off last digit, then adding extra nines and casting it on number again
    // e.g. 2.0199999999999996: +('2.019999999999999' + '9999') will give 2.02
    if (stringValue.length >= 17 && afterPoint.length > 2 && +afterPoint.substr(afterPoint.length - 3) > 995) {
        stringValue = String(+(stringValue.substr(0, afterPoint.length - 1) + '9'.repeat(stringValue.split('.').shift().length + 4)));
        [ beforePoint, afterPoint ] = String(stringValue).indexOf('.') > -1 ? stringValue.split('.') : [ stringValue, ''];
    }

    if (precision === 0) {
        return beforePoint;
    } else if (afterPoint.length > precision) {
        return `${beforePoint}.${afterPoint.substr(0, precision)}`;
    } else {
        return `${beforePoint}.${afterPoint}${'0'.repeat(precision - afterPoint.length)}`;
    }
}

Имейте в виду, что точность не может быть обработана должным образом для чисел длиной 18 и более, например, 64-битный Chrome будет округлять его или добавлять «e +» / «e-», чтобы длина номера оставалась равной 18.

Если вы хотите выполнять операции с действительными числами, то безопаснее Math.sqrt(10, precision)сначала умножить их на число , выполнить расчеты, а затем вычислить результат на величину множителя.

Пример:

0.06 + 0.01есть 0.06999999999999999, и каждая функция форматирования, которая не округляет, будет усекать его 0.06для точности 2.

Но если вы выполните ту же операцию с множителем и делителем:, (0.06 * 100 + 0.01 * 100) / 100вы получите 0.07.

Вот почему так важно использовать такой множитель / делитель при работе с реальными числами в JavaScript, особенно когда вы рассчитываете деньги ...

MagyaDEV
источник