Truncar número com duas casas decimais sem arredondamento

194

Suponha que eu tenha um valor de 15.7784514, desejo exibi-lo 15.77 sem arredondamento.

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

Resulta em -

15.8
15.78
15.778
15.7784514000 

Como eu mostro 15.77?

tempid
fonte
3
Estou tentado a perguntar, por que você não quer arredondar? Parece incorreta, não importa onde ...
Camilo Martin
38
É útil ao exibir moeda.
Richard Ye
@ mik01aj - Ao exibir moeda, é mais comum truncar valores calculados, em vez de arredondá-los. Por exemplo, a maioria dos formulários de impostos nos EUA trunca em vez de arredondar centavos fracionários calculados. Nesse caso, o valor truncado é o valor correto.
Steven Byks
4
@CamiloMartin, existe uma enorme diferença entre uma dívida de 1,49 bilhão de dólares e 1,0 bilhão de dólares.
Brode Noel
3
Há também uma enorme diferença entre 1,49 bilhão e 1,50 bilhão de dólares. São US $ 100 milhões.
Liga

Respostas:

226

Converta o número em uma string, combine o número até a segunda casa decimal:

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>

O toFixedmétodo falha em alguns casos toString, diferentemente , portanto, tenha muito cuidado com ele.

quiabo
fonte
22
+1 Isso deve resolver o problema de arredondamento. Eu ainda tinha de saída o resultado do acima usando toFixed, porém, assim: (Math.floor(value * 100) / 100).toFixed(2). Como você provavelmente sabe, coisas estranhas de precisão podem acontecer com valores de ponto flutuante (e do outro lado do espectro, se o número for 15, parece que o OP deseja 15.00).
TJ Crowder
1
hehe, ou se você combinar os dois:Number((15.7784514000*100).toString().match(/^\d+/)/100);
skobaljic 21/10
27
Math.floor (valor * 100) / 100 não funcionará se valor = 4.27 seriamente, tente.
Dark Hippo
3
@DarkHippo Isso é porque 4.27 é realmente 4.26999999999, Math.round geralmente é uma solução melhor, embora não seja a resposta para a pergunta original. Realisticamente, dado que a saída é uma string, isso deve ser feito usando manipulação de string em vez de uma solução numérica com todos os pontos fracos do ponto flutuante.
BJury
3
... isso não parece certo. A conversão entre tipos em qualquer circunstância parece rotunda e insegura. A menos que um programador realmente avançado argumente que "todos os tipos são apenas fluxos" ou algo assim.
JackHasaKeyboard
66

Atualização 5 de novembro de 2016

Nova resposta, sempre precisa

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

Como a matemática de ponto flutuante em javascript sempre terá casos extremos, a solução anterior será precisa na maior parte do tempo, o que não é bom o suficiente. Existem algumas soluções para isso num.toPrecision, como BigDecimal.js e accounting.js . No entanto, acredito que apenas analisar a string será a mais simples e sempre precisa.

Baseando a atualização no regex bem escrito da resposta aceita pelo @Gumbo, essa nova função toFixed sempre funcionará conforme o esperado.


Resposta antiga, nem sempre precisa.

Role sua própria função toFixed:

function toFixed(num, fixed) {
    fixed = fixed || 0;
    fixed = Math.pow(10, fixed);
    return Math.floor(num * fixed) / fixed;
}
guya
fonte
7
toFixed (4.56, 2) = 4.55
cryss
2
Muitas dessas respostas têm uma multiplicação dentro de uma função Math.floor (). Isso irá falhar para alguns números! A aritmética de ponto flutuante não é precisa e você precisa usar métodos diferentes.
Nico Westerdale
1
função toFixedCustom (num, fixo) {var re = new RegExp ('^ -? \\ d + (?: \. \\ d {0,' + (fixo || -1) + '})?'); if (num.toString (). match (re)) {retorna num.toString (). match (re) [0]; }}
Ryan Augustine
1
A resposta atualizada falhará para um número grande ou pequeno o suficiente para que o javascript represente em notação científica. toFixed(0.0000000052, 2)produz '5,2'. Isso pode ser corrigido usando return num.toFixed(fixed+1).match(re)[0];Aviso Estou usando toFixed com uma casa decimal acima da meta para evitar arredondamento, em seguida, executar o seu jogo regex
Netherdan
32

Optei por escrever isso em vez de remover manualmente o restante com strings, para não precisar lidar com os problemas de matemática que acompanham os números:

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

Isso fornecerá "15,77" com num = 15,7784514;

ベ ン ノ ス ケ
fonte
5
Se você não está forçando um decimal, convém adicionar um condicional caso encontre números inteiros. Assim: num = num.toString (); if (num.indexOf (".")> 0) {num = num.slice (0, (num.indexOf (".")) + 3)}; Número (num);
1112312
1
bom se ele tem decimais, mas se é um inteiro ele irá falhar
Ruslan López
Se o número for 0,00000052, será errado obter 5,2e
Vasanth
1
@ Vasanth Se o número for 0.00000052, ele retornará "0.00". Talvez a resposta tenha sido editada desde
Drenai
Sim, ele falha em casos
extremos
18

Outubro 2017

Solução geral para truncar (sem arredondamento) um número para o n-ésimo dígito decimal e convertê-lo em uma sequência com exatamente n dígitos decimais, para qualquer 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}`
}

onde x pode ser um número (que é convertido em uma sequência) ou uma sequência.

Aqui estão alguns testes para n = 2 (incluindo o solicitado pelo 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 *

* Conforme mencionado na nota, isso se deve à conversão implícita do javascript em exponencial para "1.99e-7" E para alguns outros valores de n:

15.001097   => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
SC1000
fonte
2
toFixedTrunc(0.000000199, 2) // 1.99
Maharramoff
1
@ShamkhalMaharramov: se você abrir o console de desenvolvimento e inserir 0,000000199, o que você recebe? Você recebe 1.99e-7. Além disso, se você inserir 0.000000199.toString (), o que você obtém? Você obtém "1.99e-7". Então, quando você passa 0.000000199 para a função, ele acaba trabalhando em "1.99e-7" e não em "0.000000199" e "corretamente" retorna "1.99". Veja ecma-international.org/ecma-262/6.0/…
SC1000
13

parseInt é mais rápido que 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"
Martin Varmus
fonte
2
falha com 1234567.89
Ruslan López
Você poderia elaborar Lopez?
Zardilior # 14/16
3
floorFigure (4.56, 2) = 4.55
cryss
7

Simples faça isso

number = parseInt(number * 100)/100;
Imran Pollob
fonte
4
parseInt (8.2 * 100) = 819
VPaul
6
num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)

Isso retornará 19,66

Alex Peng
fonte
5
(4.9999) .toFixed (3) .slice (0, -1) retorna 5,00, o resultado esperado é 4,99.
Bruno Lemos
1
Eu recomendo usar algo como .toFixed (6) .slice (0, -4).
Bruno Lemos
isso é perfeito, no meu caso está bom. por exemplo, se eu quero ter uso número num.toFixed (2) .slice apenas uma casa decimal (0, -1) (se num tem 1,2356, ele vai voltar 1.2)
Esteban Perez
5

Essas soluções funcionam, mas para mim parecem desnecessariamente complicadas. Pessoalmente, gosto de usar o operador de módulo para obter o restante de uma operação de divisão e removê-lo. Supondo que num = 15.7784514:

num-=num%.01;

Isso é equivalente a dizer num = num - (num% .01).

jtrick
fonte
Isso é interessante Nijkokun, obrigado por apontar. Nunca tive problemas ao usar essa técnica, mas claramente devo examinar mais de perto casos como esse. Como alternativa, você pode usar ((num * = 100) - (num% 1)) / 100, o que resolve esse problema. A prioridade no meu caso é a velocidade de execução, devido ao volume de cálculos aos quais estou aplicando isso, e esta é a maneira mais rápida de conseguir isso que encontrei.
jtrick
1
O objetivo era evitar as pesquisas e conversões de objetos e funções necessárias nas outras soluções oferecidas. Obrigado pelo feedback!
jtrick
1
também falhar com negativos quanto -5
Ruslan López
Também estou interessado em um arredondamento rápido. Como você faria esse código com 1 decimal?
thednp
5

As respostas aqui não me ajudaram, continuaram arredondando ou me dando o decimal errado.

minha solução converte seu decimal em uma string, extrai os caracteres e retorna a coisa toda como um número.

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
David D
fonte
Dec2 (99) deve retornar 99,00
VPaul
5

Minha versão para números positivos:

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

Rápido, bonito, óbvio. (versão para números positivos)

Alfa e Ômega
fonte
precisava de um não arredondamento para valores flutuantes (por exemplo, dinheiro), com apenas 1 decimal. A função acima deve ser a "resposta" deste tópico, é excelente, funciona como um encanto. um brinde ao autor e obrigado. :)))
Adrian Tanase
Falha no valor negativo. -0.7752. Teste que ele toFixed_norounding(-0.7752,2)retorna em -0.78vez de-0.77
Ling Loeng
4

O código a seguir funciona muito bem para mim:

num.toString().match(/.\*\\..{0,2}|.\*/)[0];
MISSIRIA
fonte
Vou acrescentar o sinal negativo opcional para torná-lo perfeito -?;)
Ruslan López
3

Corrigi usando as seguintes maneiras simples:

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

Os resultados serão 15,77

oms
fonte
Não funciona com valores negativos: -15.7784514retornos-15.78
Clément Baconnier
3

Apenas trunque os dígitos:

function truncDigits(inputNumber, digits) {
  const fact = 10 ** digits;
  return Math.floor(inputNumber * fact) / fact;
}
Aral Roca
fonte
3

Outra solução de linha única:

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

Usei 100 porque você deseja truncar para o segundo dígito, mas uma solução mais flexível seria:

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

onde dígitos é a quantidade de dígitos decimais a serem mantidos.

Consulte Especificações do Math.trunc para obter detalhes e compatibilidade do navegador.

remidej
fonte
1
Esta é a melhor resposta se você não precisar oferecer suporte ao IE11.
TJ.
2

Olha Você aqui. Uma resposta que mostra mais uma maneira de resolver o problema:

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

Observe o uso de + antes da expressão final. Isso é para converter nossa sequência truncada e fatiada de volta ao tipo de número.

Espero que ajude!

Jakub Barczyk
fonte
1
Gosto da simplicidade dessa abordagem e sinto que todas as soluções que evitam o uso de matemática são mais apropriadas para resolver esse problema. Portanto, o uso de slice () etc, é o caminho correto a seguir. A única vantagem do meu método é que ele processará números passados ​​que são strings [cercados por aspas [single / double]]. Por alguma razão, a função acima gerou um erro no FF, quando eu fiz: console.log ('truncate ("0.85156", 2)', truncate ("0.85156", 2));
Charles Robertson
2

truncar sem zeros

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

ou

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

teste:

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

truncar com zeros

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

teste:

toTrunc(17.4532,2)  //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1)   //1.4
toTrunc(.4,2)       //0.40
ShAkKiR
fonte
2

Isto funcionou bem para mim. Espero que isso também resolva seus problemas.

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
fonte
2

Uma maneira fácil de fazer isso é a próxima, mas é necessário garantir que o parâmetro amount seja fornecido como uma string.

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
Felipe Santa
fonte
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

Ruben Morales Felix
fonte
1

Eu costumava (num-0.05).toFixed(1)colocar o segundo decimal no chão.

王景飞
fonte
1

Minha solução em texto datilografado (pode ser facilmente portada para 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);
};

Casos de teste:

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

Alguma melhoria?

VPaul
fonte
0

Role sua própria toFixedfunção: para valores positivos Math.floorfunciona bem.

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

Para valores negativos Math.flooré o arredondamento dos valores. Então você pode usarMath.ceil .

Exemplo,

Math.ceil(-15.778665 * 10000) / 10000 = -15.7786
Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong.
Boopathi Sakthivel
fonte
5
Muitas dessas respostas têm uma multiplicação dentro de uma função Math.floor (). Isso irá falhar para alguns números! A aritmética de ponto flutuante não é precisa e você precisa usar métodos diferentes.
Nico Westerdale
0

A segunda solução da Gumbo, com a expressão regular, funciona, mas é lenta por causa da expressão regular. A primeira solução da Gumbo falha em determinadas situações devido à imprecisão no número de pontos flutuantes. Veja o JSFiddle para uma demonstração e uma referência. A segunda solução leva cerca de 1636 nanossegundos por chamada no meu sistema atual, CPU Intel Core i5-2500 a 3,30 GHz.

A solução que eu escrevi envolve adicionar uma pequena compensação para cuidar da imprecisão de ponto flutuante. É basicamente instantâneo, ou seja, da ordem de nanossegundos. Cronometrei 2 nanossegundos por chamada, mas os timers do JavaScript não são muito precisos ou granulares. Aqui está o JS Fiddle e o código.

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);
Daniel Barbalace
fonte
0

Com base na resposta de David D :

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
Charles Robertson
fonte
0

É mais confiável obter dois pontos flutuantes sem arredondar.

Resposta de referência

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

Obrigado !

Jaydeep Mor
fonte
0

Já existe uma resposta adequada com expressão regular e cálculo aritmético, você também pode tentar isso

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
rei neo
fonte
0

Aqui está o que fez com string

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;
}
Kishan Vaghela
fonte
0

Todas essas respostas parecem um pouco complicadas. Eu apenas subtrairia 0,5 do seu número e usaria toFixed ().

Sean Mayes
fonte
Você quis dizer 0,005?
Luan Nguyen
0

A solução mais eficiente (para dois dígitos da fração) é subtrair 0,005 antes de chamar toFixed()

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

Os números negativos também serão arredondados para baixo (longe de zero). O OP não falou nada sobre números negativos.

Wiimm
fonte
0

Sei que já existem poucos exemplos de trabalho, mas acho que vale a pena propor meu equivalente String.toFixed, alguns podem achar útil.

Essa é a minha alternativa toFixed, que não arredonda números, apenas o trunca ou adiciona zeros de acordo com a precisão fornecida. Para um número extra longo, ele usa o arredondamento JS embutido quando a precisão é longa. A função funciona para todos os números problemáticos que encontrei na pilha.

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)}`;
    }
}

Lembre-se de que a precisão pode não ser tratada adequadamente para números de comprimento 18 e superior; por exemplo, o Chrome de 64 bits o arredondará ou adicionará "e +" / "e-" para manter o comprimento do número em 18.

Se você deseja executar operações em números reais, é mais seguro multiplicá-lo por Math.sqrt(10, precision) primeiro, faça os cálculos e depois mergulhe o resultado pelo valor do multiplicador.

Exemplo:

0.06 + 0.01é 0.06999999999999999, e toda função de formatação que não seja arredondada a truncará 0.06para precisão2 .

Mas se você realizar a mesma operação com multiplicador e divisor:, (0.06 * 100 + 0.01 * 100) / 100obterá 0.07.

É por isso que é tão importante usar esse multiplicador / divisor ao lidar com números reais em javascript, especialmente quando você está calculando dinheiro ...

MagyaDEV
fonte