Pergunta

Em JavaScript, a maneira típica de arredondar um número para n lugares decimais é algo como:

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

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

console.log(roundNumber(0.1 + 0.2, 2));
console.log(roundNumber(2.1234, 2));

No entanto, essa abordagem vai arredondar para um máximo de n lugares decimais enquanto eu quero sempre arredondando para n lugares decimais. Por exemplo, "2.0" seria arredondado para "2".

Alguma ideia?

Foi útil?

Solução

Isso não é um placar de arredondamento, é um problema de exibição. Um número não contém informações sobre dígitos significativos; O valor 2 é o mesmo que 2.0000000000000. É quando você transforma o valor arredondado em uma string que a faz exibir um certo número de dígitos.

Você pode simplesmente adicionar zeros após o número, algo como:

var s = number.toString();
if (s.indexOf('.') == -1) s += '.';
while (s.length < s.indexOf('.') + 4) s += '0';

(Observe que isso pressupõe que as configurações regionais do cliente usam o período como separador decimal, o código precisa de mais trabalho para funcionar para outras configurações.)

Outras dicas

Eu acho que há uma abordagem mais simples para todos os dados aqui, e é o método Number.toFixed() já implementado em JavaScript.

Basta escrever:

var myNumber = 2;

myNumber.toFixed(2); //returns "2.00"
myNumber.toFixed(1); //returns "2.0"

etc ...

Eu encontrei um caminho. Este é o código de Christoph com uma correção:

function toFixed(value, precision) {
    var precision = precision || 0,
        power = Math.pow(10, precision),
        absValue = Math.abs(Math.round(value * power)),
        result = (value < 0 ? '-' : '') + String(Math.floor(absValue / power));

    if (precision > 0) {
        var fraction = String(absValue % power),
            padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');
        result += '.' + padding + fraction;
    }
    return result;
}

Leia os detalhes de repetir um personagem usando um construtor de matriz aqui Se você está curioso para saber por que adicionei o "+ 1".

Sempre há uma maneira melhor de fazer as coisas.

var number = 51.93999999999761;

Eu gostaria de obter quatro dígitos precisão: 51.94

apenas faça:

number.toPrecision(4);

O resultado será: 51,94

Método de arredondamento semelhante a PHP

O código abaixo pode ser usado para adicionar sua própria versão do Math.Round ao seu próprio espaço para nome que pega um parâmetro de precisão. Ao contrário do arredondamento decimal no exemplo acima, isso não executa a conversão de e para as cordas, e o parâmetro de precisão funciona da mesma maneira que o PHP e o excel, pelo qual um 1 positivo chegaria a 1 local decimal e -1 arredondaria para as dezenas.

var myNamespace = {};
myNamespace.round = function(number, precision) {
    var factor = Math.pow(10, precision);
    var tempNumber = number * factor;
    var roundedTempNumber = Math.round(tempNumber);
    return roundedTempNumber / factor;
};

myNamespace.round(1234.5678, 1); // 1234.6
myNamespace.round(1234.5678, -1); // 1230

a partir de Referência do desenvolvedor da Mozilla para Math.Round ()

Esperançosamente, o código de trabalho (não fez muitos testes):

function toFixed(value, precision) {
    var precision = precision || 0,
        neg = value < 0,
        power = Math.pow(10, precision),
        value = Math.round(value * power),
        integral = String((neg ? Math.ceil : Math.floor)(value / power)),
        fraction = String((neg ? -value : value) % power),
        padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');

    return precision ? integral + '.' +  padding + fraction : integral;
}

Isso funciona para arredondamento para n dígitos (se você apenas deseja truncar para n dígitos, remova a chamada em matemática e use a matemática.

function roundN(value, digits) {
   var tenToN = 10 ** digits;
   return /*Math.trunc*/(Math.round(value * tenToN)) / tenToN;
}

Teve que recorrer a essa lógica em Java no passado, quando eu estava autorizando componentes de manipulação de dados de manipulação de dados. Isso ocorre desde que eu descobri que adicionar 0,1 muitas vezes a 0 você acabaria com uma parte decimal inesperadamente longa (isso se deve a aritmética de ponto flutuante).

Um comentário de usuário em Número de formato para sempre mostrar 2 lugares decimais chama essa técnica de escala.

Alguns mencionam que existem casos que não redondam como esperado e em http://www.jacklmoore.com/notes/Rounding-in-javascript/ Isso é sugerido:

function round(value, decimals) {
  return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}

Aqui está um link para um javascript sprintf,

http://www.webtoolkit.info/javascript-sprintf.html

Uma chamada para sprintf () é uma metodologia de arredondamento em Perl, mas o JavaScript não tem essa função nativamente.

http://perldoc.perl.org/functions/sprintf.html

Isso ajuda?

Eu acho que abaixo a função pode ajudar

function roundOff(value,round) {
   return (parseInt(value * (10 ** (round + 1))) - parseInt(value * (10 ** round)) * 10) > 4 ? (((parseFloat(parseInt((value + parseFloat(1 / (10 ** round))) * (10 ** round))))) / (10 ** round)) : (parseFloat(parseInt(value * (10 ** round))) / ( 10 ** round));
}

Uso: roundOff(600.23458,2); retornará 600.23

Se você realmente não se importa com o arredondamento, basta adicionar um tofixado (x) e depois remover 0es à direita e o ponto, se necessário. Não é uma solução rápida.

function format(value, decimals) {
    if (value) {
        value = value.toFixed(decimals);            
    } else {
        value = "0";
    }
    if (value.indexOf(".") < 0) { value += "."; }
    var dotIdx = value.indexOf(".");
    while (value.length - dotIdx <= decimals) { value += "0"; } // add 0's

    return value;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top