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



Предположим, у меня есть значение 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?

262   25  

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

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

num.toString().match(/.\*\..{0,2}|.\*/)[0];

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

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

быстро, красиво, очевидно.

num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)

это вернет 19.66

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

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

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

просто сделать это

number = parseInt(number * 100)/100;

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

// 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);

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

дом на Дэвид Д ответ:

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

    Ничего не найдено.