Усекает число до двух знаков после запятой без округления
Предположим, у меня есть значение 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?
25 ответов:
преобразуйте число в строку, сопоставьте число до второго десятичного знака:
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>The
toFixedметод не работает в некоторых случаях в отличие отtoString, Так что будьте очень осторожны с ним.
Обновление 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 и Бухгалтерский учет.js. Тем не менее, я считаю, что просто разбор строки будет самым простым и всегда точны.базирование обновление хорошо написанного регулярного выражения из принятого ответа @Gumbo, эта новая функция toFixed всегда будет работать так, как ожидалось.
старый ответ, не всегда точны.
сверните свою собственную функцию toFixed:
function toFixed(num, fixed) { fixed = fixed || 0; fixed = Math.pow(10, fixed); return Math.floor(num * fixed) / fixed; }
Я решил написать это вместо того, чтобы вручную удалить остаток со строками, поэтому мне не нужно иметь дело с математическими проблемами, которые приходят с числами:
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" с num = 15.7784514;
parseInt быстрее, чем математика.этаж
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"
октября 2017
общее решение усечь (без округления) любое число до n-й десятичной цифры и преобразовать его в строку с ровно n десятичными цифрами, для любого n≥0.
function toFixedTrunc(value, n) { const v = value.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}` }вот некоторые тесты для n=2 (в том числе запрошенный OP):
0 => 0.00 0.01 => 0.01 0.2372 => 0.23 0.5839 => 0.58 0.999 => 0.99 1 => 1.00 1.01 => 1.01 2 => 2.00 2.551 => 2.55 2.5 => 2.50 2.99999 => 2.99 4.27 => 4.27 15.7784514 => 15.77 123.5999 => 123.59Пожалуйста, обратите внимание, что в то время как выше работает всегда, чисто числовой подход не будет. Например, рассмотрим следующую функцию (или любую аналогичную один):
function toFixedTrunc(value, n) { const f = Math.pow(10, n); return (Math.trunc(value*f)/f).toFixed(n); }хотя концептуально правильно, это не сработает с некоторыми иррациональными числами, например 4.27, из-за того, как числа представлены внутри.
эти решения действительно работают, но мне кажутся излишне сложными. Мне лично нравится использовать оператор модуля для получения оставшейся части операции деления и удалить ее. Предполагая, что num = 15.7784514:
num-=num%.01;Это эквивалентно высказыванию num = num - (num % .01).
ответы здесь мне не помогли, он продолжал округлять или давать мне неправильную десятичную дробь.
мое решение преобразует десятичное число в строку, извлекает символы, а затем возвращает все в ряд.
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
моя версия для положительных чисел:
function toFixed_norounding(n,p) { var result = n.toFixed(p); return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p); }быстро, красиво, очевидно.
я исправил, используя следующий простой способ -
var num = 15.7784514; Math.floor(num*100)/100;результаты будут 15.77
вот ты где. Ответ, который показывает еще один способ решения проблемы:
// 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)); }обратите внимание на использование + перед окончательным выражением. То есть преобразовать нашу усеченную, нарезанную строку обратно в числовой тип.
надеюсь, что это помогает!
усечь без нулей
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)); }
еще одно однострочное решение:
number = Math.trunc(number*100)/100я использовал 100, потому что вы хотите усечь до второй цифры, но более гибкое решение будет :
number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)где цифры-это количество десятичных цифр, сохранить.
свернуть свой собственный
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.
Гамбо с регулярным выражением, работает, но медленно из-за регулярного выражения. Первое решение Гамбо терпит неудачу в определенных ситуациях из-за неточности в числах с плавающей запятой. Смотрите 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);
дом на Дэвид Д ответ:
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
более надежно получить две плавающие точки без округления.
var number = 10.5859; var fixed2FloatPoints = parseInt(number * 100) / 100; console.log(fixed2FloatPoints);Спасибо !
уже есть некоторые подходящие ответы с регулярным выражением и арифметическим расчетом, вы также можете попробовать это
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
вот что он сделал со строкой
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; }
простой способ сделать это следующий:
function truncate(amount, decimals = 2){ const approach = Math.pow(10, decimals); return Math.floor(amount * approach )/approach; } console.log(truncate(7.99999)); //OUTPUT 7.99 console.log(truncate(7.99999, 3)); //OUTPUT 7.999
спасибо Мартин Вармус
function floorFigure(figure, decimals){ if (!decimals) decimals = 2; var d = Math.pow(10,decimals); return ((figure*d)/d).toFixed(decimals); }; floorFigure(123.5999) => "123.59" floorFigure(123.5999, 3) => "123.599"Я делаю простое обновление, и я получил надлежащее округление. Обновление находится в следующей строке
return ((figure*d)/d).toFixed(decimals);удалить функцию parseInt ()
вот еще один вариант для спасения .toFixed ([цифры]) функционал без округления переменной float:
Number.prototype.toRealFixed = function(digits) { return Math.floor(this.valueOf() * Math.pow(10, digits)) / Math.pow(10, digits); };и звонок:
var float_var = 0.02209062; float_var.toRealFixed();
Comments