Formatar um número com exatamente duas casas decimais em JavaScript

571

Eu tenho essa linha de código que arredonda meus números para duas casas decimais. Mas recebo números como este: 10.8, 2.4, etc. Não é minha idéia de duas casas decimais; portanto, como posso melhorar o seguinte?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

Quero números como 10.80, 2.40, etc. O uso do jQuery é bom para mim.

Abdômen
fonte
1
Seu código é exatamente o que eu estava procurando (para reduzir a precisão de flutuação para 7 casas decimais para um arquivo JSON menor) Ignorando Math.pow para velocidade val = Math.round (val * 10000000) / 10000000);
Pawel
Como a resposta atualmente aceita dá indiscutivelmente um resultado errado para uma ampla gama de valores graças a agravar imprecisão inerente aos números ( 0.565, 0.575, 1.005), eu posso sugerir olhando de novo para esta resposta , que recebe-los corrigir?
TJ Crowder
Talvez você queira incluir uma biblioteca sprintf para JavaScript stackoverflow.com/questions/610406/…
Thilo
Após o arredondamento correto com o método de deslocamento e arredondamento da casa decimal, você pode usar o number.toFixed(x)método para convertê-lo em uma sequência com a quantidade necessária de zeros. Por exemplo, arredonde 1.34para 1.3com o método entre navegadores e adicione 1 zero e converta em string com 1.3.toFixed(2)(para obter "1.30").
Edward

Respostas:

999

Para formatar um número usando a notação de ponto fixo, você pode simplesmente usar o método toFixed :

(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"

Observe que toFixed()retorna uma string.

IMPORTANTE : Observe que toFixed não arredonda 90% das vezes, ele retornará o valor arredondado, mas, em muitos casos, não funciona.

Por exemplo:

2.005.toFixed(2) === "2.00"

ATUALIZAR:

Atualmente, você pode usar o Intl.NumberFormatconstrutor. Faz parte da Especificação da API de internacionalização do ECMAScript (ECMA402). Ele tem suporte muito bom navegador , incluindo até mesmo IE11, e é totalmente suportado no Node.js .

const formatter = new Intl.NumberFormat('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});

console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"

Como alternativa, você pode usar o toLocaleStringmétodo, que internamente usará a IntlAPI:

const format = (num, decimals) => num.toLocaleString('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});


console.log(format(2.005)); // "2.01"
console.log(format(1.345)); // "1.35"

Essa API também oferece uma ampla variedade de opções para formatar, como milhares de separadores, símbolos de moeda, etc.

CMS
fonte
17
Não funciona de forma consistente em todos os navegadores, ou seja, (0.09).toFixed(1);dá 0,0 no IE8
ajbeaven
41
Fixed não arredonda, você pode fazer isso primeiro: (Math.round (0.09)). toFixed (1);
rekans
32
@rekans: Isso está errado. Math.Round(0.09)retornará 0para que isso irá sempre dar 0.0...
Chris
28
Essa é uma má ideia na maioria das situações, pois, em alguns casos, converte o número em uma string ou número de ponto flutuante.
Ash Azul
80
Tem que concordar com o @AshBlue aqui ... isso só é seguro para formatar a apresentação de valores. Pode quebrar o código com outros cálculos. Caso contrário, Math.round(value*100)/100funciona melhor para 2DP.
UpTheCreek
98

Este é um tópico antigo, mas ainda assim obtém os melhores resultados do Google e as soluções oferecidas compartilham o mesmo problema de decimais de ponto flutuante. Aqui está a função (muito genérica) que eu uso, graças ao MDN :

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

  // Shift back
  value = value.toString().split('e');
  return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}

Como podemos ver, não temos esses problemas:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

Essa genicidade também fornece algumas coisas legais:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

Agora, para responder à pergunta do OP, é preciso digitar:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

Ou, para uma função mais concisa e menos genérica:

function round2Fixed(value) {
  value = +value;

  if (isNaN(value))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));

  // Shift back
  value = value.toString().split('e');
  return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}

Você pode chamá-lo com:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

Vários exemplos e testes (graças a @ tj-crowder !):

astorije
fonte
1
Como não há uma maneira simples de fazer isso? ES6 para o resgate?
zero_cool
Obrigado por postar o polyfill MDN. Na página MDN vinculada, o polyfill não está mais lá. Eu quero saber porque ele foi removido ...
Rei Holly
43

Normalmente, eu adiciono isso à minha biblioteca pessoal e, depois de algumas sugestões e usando a solução @TIMINeutron também, e tornando-a adaptável para o tamanho decimal, este se encaixa melhor:

function precise_round(num, decimals) {
   var t = Math.pow(10, decimals);   
   return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

funcionará para as exceções relatadas.

Miguel
fonte
2
precis_round (1.275,2) é 1,27?
allenhwkim
2
@Imre Altere o valor de retorno para (Math.round (num * Math.pow (10, decimais)) / Math.pow (10, decimais)). ToFixed (2); e você não terá mais esse problema.
dkroy
6
onde você declara "sign" e "dec" se sua segunda função é escolhida como deveria, não deveria tê-las como indefinidas?
Ady Ngom
2
Adicionei uma solução alternativa para o método de sinal de missign no IE: gist.github.com/ArminVieweg/28647e735aa6efaba401
Armin
1
@Armin Sua correção também a faz funcionar no Safari. A função original não funcionou no Safari.
31415 Dave
19

Não sei por que não consigo adicionar um comentário a uma resposta anterior (talvez eu esteja irremediavelmente cego, não sei), mas eu vim com uma solução usando a resposta de @ Miguel:

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

E seus dois comentários (de @bighostkim e @Imre):

  • Problema ao precise_round(1.275,2)não retornar 1,28
  • Problema em precise_round(6,2)não retornar 6,00 (como ele queria).

Minha solução final é a seguinte:

function precise_round(num,decimals) {
    var sign = num >= 0 ? 1 : -1;
    return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

Como você pode ver, eu tive que adicionar um pouco de "correção" (não é o que é, mas como o Math.round está com perdas - você pode conferir no jsfiddle.net - esta é a única maneira que eu sabia "corrigir " isto). Ele adiciona 0,001 ao número já preenchido, adicionando 1três 0s à direita do valor decimal. Portanto, deve ser seguro usar.

Depois disso, adicionei .toFixed(decimal)para sempre imprimir o número no formato correto (com a quantidade correta de decimais).

Então é isso mesmo. Use bem ;)

EDIT: funcionalidade adicionada à "correção" de números negativos.

tfrascaroli
fonte
2
A "correção" é na maior parte segura, mas, por exemplo, precise_round(1.27499,2)agora também retorna 1,28 ... Não Math.roundé com perdas; da maneira que os computadores armazenam internamente valores de ponto flutuante. Basicamente, você está condenado a falhar com alguns valores antes que os dados fica ainda à sua função :)
Imre
@ Imre, você está absolutamente certo. É por isso que explico o que esse 0,001 está fazendo lá, caso alguém queira torná-lo "mais preciso " ou até excluí-lo (se você tiver um super computador com 2 Mbytes por bóia, o que eu acho que ninguém faz aqui ;)
tfrascaroli
1
Na verdade, a especificação da linguagem é bastante específica sobre o uso de 64 bits para valores numéricos, assim que ter / usando um supercomputador não mudaria nada :)
Imre
para 0,001, você pode substituir adicionando muitos zeros de acordo com o comprimento das casas decimais. então ..
Miguel
15

Uma maneira de ter 100% de certeza de obter um número com 2 casas decimais:

(Math.round(num*100)/100).toFixed(2)

Se isso causar erros de arredondamento, você pode usar o seguinte, como James explicou em seu comentário:

(Math.round((num * 1000)/10)/100).toFixed(2)
Gerard de Visser
fonte
6
Essa é a melhor e mais simples maneira de fazer isso. No entanto, devido à matemática do ponto flutuante, 1.275 * 100 = 127.49999999999999, o que poderia causar erros menores no arredondamento. Para corrigir isso, podemos multiplicar por 1000 e dividir por 10, como (1,275 * 1000) / 10 = 127,5. Como segue: var answer = (Math.round((num * 1000)/10)/100).toFixed(2);
James Gould
(Math.round ((1.015 * 1000) / 10) / 100) .toFixed (2) ainda fornece 1,01, não deveria ser 1,02?
gaurav5430
14

toFixed (n) fornece n comprimento após o ponto decimal; toPrecision (x) fornece x comprimento total.

Use este método abaixo

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

E se você quiser que o número seja corrigido, use

result = num.toFixed(2);
Syed Umar Ahmed
fonte
ele não funciona bem ... para o número num = 50,2349 você deve escrever toPrecision (3) para obter 50,2
Piotr Czyż
é apenas um exemplo, você pode alterá-lo conforme sua necessidade @ PiotrCzyż
Syed Ahmed Umar
5

Não encontrei uma solução precisa para esse problema, então criei a minha:

function inprecise_round(value, decPlaces) {
  return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}

function precise_round(value, decPlaces){
    var val = value * Math.pow(10, decPlaces);
    var fraction = (Math.round((val-parseInt(val))*10)/10);

    //this line is for consistency with .NET Decimal.Round behavior
    // -342.055 => -342.06
    if(fraction == -0.5) fraction = -0.6;

    val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
    return val;
}

Exemplos:

function inprecise_round(value, decPlaces) {
  return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

function precise_round(value, decPlaces) {
  var val = value * Math.pow(10, decPlaces);
  var fraction = (Math.round((val - parseInt(val)) * 10) / 10);

  //this line is for consistency with .NET Decimal.Round behavior
  // -342.055 => -342.06
  if (fraction == -0.5) fraction = -0.6;

  val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
  return val;
}

// This may produce different results depending on the browser environment
console.log("342.055.toFixed(2)         :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10

console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05
console.log("precise_round(342.055, 2)  :", precise_round(342.055, 2));   // 342.06
console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2));  // -342.06

console.log("inprecise_round(0.565, 2)  :", inprecise_round(0.565, 2));   // 0.56
console.log("precise_round(0.565, 2)    :", precise_round(0.565, 2));     // 0.57

Florian Ignaz Eßl
fonte
2
Obrigado. Aqui está um detalhe para testar isso: jsfiddle.net/lamarant/ySXuF . Estou aplicando toFixed () ao valor anterior ao retorno, que acrescenta o número correto de zeros ao final do valor retornado.
Lamarant 07/07
não está funcionando para o valor = 0,004990845956707237 e inprecise_round (valor, 8) retorna 0,00499085, mas deve retornar 0,00499084 #
MERT
3

O @heridev e eu criamos uma pequena função no jQuery.

Você pode tentar a seguir:

HTML

<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​

jQuery

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
    $('.two-digits').keyup(function(){
        if($(this).val().indexOf('.')!=-1){         
            if($(this).val().split(".")[1].length > 2){                
                if( isNaN( parseFloat( this.value ) ) ) return;
                this.value = parseFloat(this.value).toFixed(2);
            }  
         }            
         return this; //for chaining
    });
});

DEMO ONLINE:

http://jsfiddle.net/c4Wqn/

vicmaster
fonte
1
Eu posso apreciar a contribuição, embora eu ache que adicionar elementos DOM e jQuery à mistura pareça estar fora do escopo da questão.
21413 Chris May
Você não deve ouvir o evento keyup, pois ele parece muito ruim e não é ativado quando você adiciona algo ao script. Prefiro ouvir o inputevento. Isso não cria um efeito de oscilação e também é acionado quando você acessa o campo com JS
Le 'nton 26/11/15
3

O problema com os valores de ponto flutuante é que eles estão tentando representar uma quantidade infinita de valores (contínuos) com uma quantidade fixa de bits. Então, naturalmente, deve haver alguma perda no jogo, e você será mordido com alguns valores.

Quando um computador armazena 1.275 como um valor de ponto flutuante, na verdade não se lembra se era 1.275 ou 1.27499999999999993 ou mesmo 1.27500000000000002. Esses valores devem fornecer resultados diferentes após o arredondamento para duas casas decimais, mas não o serão, pois, para o computador, parecem exatamente os mesmos após o armazenamento como valores de ponto flutuante, e não há como restaurar os dados perdidos. Quaisquer cálculos adicionais acumularão essa imprecisão.

Portanto, se a precisão importa, você deve evitar valores de ponto flutuante desde o início. As opções mais simples são:

  • use uma biblioteca dedicada
  • use cadeias de caracteres para armazenar e passar os valores (acompanhados de operações de cadeia de caracteres)
  • use números inteiros (por exemplo, você pode passar a quantia de centésimos do seu valor real, por exemplo, quantia em centavos em vez da quantia em dólares)

Por exemplo, ao usar números inteiros para armazenar o número de centésimos, a função para encontrar o valor real é bastante simples:

function descale(num, decimals) {
    var hasMinus = num < 0;
    var numString = Math.abs(num).toString();
    var precedingZeroes = '';
    for (var i = numString.length; i <= decimals; i++) {
        precedingZeroes += '0';
    }
    numString = precedingZeroes + numString;
    return (hasMinus ? '-' : '') 
        + numString.substr(0, numString.length-decimals) 
        + '.' 
        + numString.substr(numString.length-decimals);
}

alert(descale(127, 2));

Com seqüências de caracteres, você precisará arredondar, mas ainda é gerenciável:

function precise_round(num, decimals) {
    var parts = num.split('.');
    var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
    var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
    var decimalPart = parts.length > 1 ? parts[1] : '';
    if (decimalPart.length > decimals) {
        var roundOffNumber = decimalPart.charAt(decimals);
        decimalPart = decimalPart.substr(0, decimals);
        if ('56789'.indexOf(roundOffNumber) > -1) {
            var numbers = integralPart + decimalPart;
            var i = numbers.length;
            var trailingZeroes = '';
            var justOneAndTrailingZeroes = true;
            do {
                i--;
                var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
                if (roundedNumber === '0') {
                    trailingZeroes += '0';
                } else {
                    numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
                    justOneAndTrailingZeroes = false;
                    break;
                }
            } while (i > 0);
            if (justOneAndTrailingZeroes) {
                numbers = '1' + trailingZeroes;
            }
            integralPart = numbers.substr(0, numbers.length - decimals);
            decimalPart = numbers.substr(numbers.length - decimals);
        }
    } else {
        for (var i = decimalPart.length; i < decimals; i++) {
            decimalPart += '0';
        }
    }
    return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

Observe que esta função arredonda para o mais próximo, desvia do zero , enquanto o IEEE 754 recomenda arredondar para o mais próximo, desvia para o mesmo como o comportamento padrão para operações de ponto flutuante. Tais modificações são deixadas como um exercício para o leitor :)

Imre
fonte
3

Aqui está um simples

function roundFloat(num,dec){
    var d = 1;
    for (var i=0; i<dec; i++){
        d += "0";
    }
    return Math.round(num * d) / d;
}

Use como alert(roundFloat(1.79209243929,4));

Jsfiddle

ow3n
fonte
2

Arredonde seu valor decimal e use toFixed(x)para o (s) dígito (s) esperado (s).

function parseDecimalRoundAndFixed(num,dec){
  var d =  Math.pow(10,dec);
  return (Math.round(num * d) / d).toFixed(dec);
}

Ligar

parseDecimalRoundAndFixed (10.800243929,4) => 10.80 parseDecimalRoundAndFixed (10.807243929,2) => 10.81

HATCHA
fonte
2

Arredondar para baixo

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

Arredondar para cima

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Rodada mais próxima

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Https://stackoverflow.com/a/7641824/1889449 mesclado e https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm Obrigado.

MERT DOĞAN
fonte
2

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

// testing some -ve 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

Amr Ali
fonte
2

Aqui está minha solução de 1 linha: Number((yourNumericValueHere).toFixed(2));

Aqui está o que acontece:

1) Primeiro, você aplica .toFixed(2)o número ao qual deseja arredondar as casas decimais de. Observe que isso converterá o valor em uma seqüência de caracteres do número. Portanto, se você estiver usando o Typecript, ocorrerá um erro como este:

"O tipo 'string' não pode ser atribuído ao tipo 'number'"

2) Para recuperar o valor numérico ou converter a string em valor numérico, basta aplicar a Number()função no chamado valor de 'string'.

Para esclarecimentos, veja o exemplo abaixo:

EXEMPLO: Eu tenho uma quantidade que tem até 5 dígitos nas casas decimais e gostaria de encurtá-la para até 2 casas decimais. Eu faço assim:

var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);

Devner
fonte
1

Coloque o seguinte em algum escopo global:

Number.prototype.getDecimals = function ( decDigCount ) {
   return this.toFixed(decDigCount);
}

e tente :

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

Atualizar

Observe que toFixed()só pode funcionar para o número de casas decimais entre 0-20ie, a.getDecimals(25)pode gerar um erro javascript, portanto, para acomodar que você pode adicionar alguma verificação adicional, ou seja,

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}
Kamran Ahmed
fonte
1
Number(((Math.random() * 100) + 1).toFixed(2))

isso retornará um número aleatório de 1 a 100 arredondado para 2 casas decimais.

Johnathan Ralls
fonte
1

Usando esta resposta por referência: https://stackoverflow.com/a/21029698/454827

Eu construo uma função para obter números dinâmicos de decimais:

function toDec(num, dec)
{
        if(typeof dec=='undefined' || dec<0)
                dec = 2;

        var tmp = dec + 1;
        for(var i=1; i<=tmp; i++)
                num = num * 10;

        num = num / 10;
        num = Math.round(num);
        for(var i=1; i<=dec; i++)
                num = num / 10;

        num = num.toFixed(dec);

        return num;
}

aqui exemplo de trabalho: https://jsfiddle.net/wpxLduLc/

ZiTAL
fonte
1

parse = function (data) {
       data = Math.round(data*Math.pow(10,2))/Math.pow(10,2);
       if (data != null) {
            var lastone = data.toString().split('').pop();
            if (lastone != '.') {
                 data = parseFloat(data);
            }
       }
       return data;
  };

$('#result').html(parse(200)); // output 200
$('#result1').html(parse(200.1)); // output 200.1
$('#result2').html(parse(200.10)); // output 200.1
$('#result3').html(parse(200.109)); // output 200.11
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="result"></div>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>

Vishnu T Asok
fonte
1

Com esses exemplos, você ainda receberá um erro ao tentar arredondar o número 1.005, a solução é usar uma biblioteca como Math.js ou esta função:

function round(value: number, decimals: number) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
David Webster
fonte
1

Eu recebi algumas idéias deste post alguns meses atrás, mas nenhuma das respostas aqui, nem as respostas de outros posts / blogs poderiam lidar com todos os cenários (por exemplo, números negativos e alguns "números da sorte" encontrados pelo nosso testador). No final, nosso testador não encontrou nenhum problema com este método abaixo. Colar um trecho do meu código:

fixPrecision: function (value) {
    var me = this,
        nan = isNaN(value),
        precision = me.decimalPrecision;

    if (nan || !value) {
        return nan ? '' : value;
    } else if (!me.allowDecimals || precision <= 0) {
        precision = 0;
    }

    //[1]
    //return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
    precision = precision || 0;
    var negMultiplier = value < 0 ? -1 : 1;

    //[2]
    var numWithExp = parseFloat(value + "e" + precision);
    var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
    return parseFloat(roundedNum.toFixed(precision));
},

Também tenho comentários de código (desculpe, já esqueci todos os detalhes) ... Estou postando minha resposta aqui para referência futura:

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).
remondo
fonte
0

Estou resolvendo o problema do modificador. Suporta apenas 2 decimais.

$(function(){
  //input number only.
  convertNumberFloatZero(22); // output : 22.00
  convertNumberFloatZero(22.5); // output : 22.50
  convertNumberFloatZero(22.55); // output : 22.55
  convertNumberFloatZero(22.556); // output : 22.56
  convertNumberFloatZero(22.555); // output : 22.55
  convertNumberFloatZero(22.5541); // output : 22.54
  convertNumberFloatZero(22222.5541); // output : 22,222.54

  function convertNumberFloatZero(number){
	if(!$.isNumeric(number)){
		return 'NaN';
	}
	var numberFloat = number.toFixed(3);
	var splitNumber = numberFloat.split(".");
	var cNumberFloat = number.toFixed(2);
	var cNsplitNumber = cNumberFloat.split(".");
	var lastChar = splitNumber[1].substr(splitNumber[1].length - 1);
	if(lastChar > 0 && lastChar < 5){
		cNsplitNumber[1]--;
	}
	return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

bamossza
fonte
0
(Math.round((10.2)*100)/100).toFixed(2)

Isso deve render: 10.20

(Math.round((.05)*100)/100).toFixed(2)

Isso deve render: 0.05

(Math.round((4.04)*100)/100).toFixed(2)

Isso deve render: 4.04

etc.

Anthony Ruffino
fonte
0

/*Due to all told stuff. You may do 2 things for different purposes:
When showing/printing stuff use this in your alert/innerHtml= contents:
YourRebelNumber.toFixed(2)*/

var aNumber=9242.16;
var YourRebelNumber=aNumber-9000;
alert(YourRebelNumber);
alert(YourRebelNumber.toFixed(2));

/*and when comparing use:
Number(YourRebelNumber.toFixed(2))*/

if(YourRebelNumber==242.16)alert("Not Rounded");
if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded");

/*Number will behave as you want in that moment. After that, it'll return to its defiance.
*/

Christian Læirbag
fonte
0

Isso é muito simples e funciona tão bem quanto qualquer outro:

function parseNumber(val, decimalPlaces) {
    if (decimalPlaces == null) decimalPlaces = 0
    var ret = Number(val).toFixed(decimalPlaces)
    return Number(ret)
}

Como toFixed () só pode ser chamado em números e, infelizmente, retorna uma string, isso faz toda a análise para você nas duas direções. Você pode passar uma string ou um número e sempre recebe um número de volta! Chamar parseNumber (1.49) fornecerá 1 e parseNumber (1.49,2) fornecerá 1,50. Assim como o melhor deles!

Aaron Dake
fonte
0

Você também pode usar o .toPrecision()método e algum código personalizado e sempre arredondar para o enésimo dígito decimal, independentemente do comprimento da parte int.

function glbfrmt (number, decimals, seperator) {
    return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

Você também pode torná-lo um plug-in para um melhor uso.

leo_lo
fonte
-1

Simples assim.

var rounded_value=Math.round(value * 100) / 100;
Gihan Gamage
fonte
1
Errado. Tente 1.015
Marco Marsala
-2

Eu encontrei uma maneira muito simples que resolveu esse problema para mim e pode ser usada ou adaptada:

td[row].innerHTML = price.toPrecision(price.toFixed(decimals).length

fonte
-4

100% trabalhando !!! Tente

<html>
     <head>
      <script>
      function replacePonto(){
        var input = document.getElementById('qtd');
        var ponto = input.value.split('.').length;
        var slash = input.value.split('-').length;
        if (ponto > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        if(slash > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        input.value=input.value.replace(/[^0-9.-]/,'');

        if (ponto ==2)
	input.value=input.value.substr(0,(input.value.indexOf('.')+3));

if(input.value == '.')
	input.value = "";
              }
      </script>
      </head>
      <body>
         <input type="text" id="qtd" maxlength="10" style="width:140px" onkeyup="return replacePonto()">
      </body>
    </html>

JONAS MAGALHAES DOS SANTOS
fonte
Bem-vindo ao SO. Por favor, leia este tutorial e siga as orientações para responder.
thewaywewere