var soma = parseFloat(input1) + parseFloat(input2);
O valor esperado na variável soma seria 4,44 infelizmente este não é o valor obtido, devido à precisão do float que não representa o número exactamente como lhe é passado, obtemos sim o valor 4,439999999. Para resolver este problema desenvolvi o seguinte algoritmo que possibilita truncar as casas decimais de um número.
//num = número a formatar; nDecimals = número de casas decimais
function Precision(num, nDecimals){
var toReturn = "";
num = "" + num;
var pointIdx = num.indexOf('.');
//garantir que é decimal
if(pointIdx == -1){
num += '.';
pointIdx = num.indexOf('.');
}
var limit = pointIdx + nDecimals + 1;
//quando se tem mais casas decimais que aquelas que se pretende
if(num.length > limit){
//arredondar para baixo
if(num[limit] < '5')
{
for(var iter = 0; iter < limit; ++iter)
{
toReturn += num.charAt(iter);
}
return toReturn;
}
//arredondar para cima
else{
for(var iter = 0; iter < pointIdx + nDecimals; ++iter){
toReturn += num.charAt(iter);
}
var lastNum = parseInt(num.charAt(pointIdx + nDecimals)) + parseInt(1);
toReturn += lastNum;
return toReturn;
}
}
//acrescentar 0s à direita se necessário
if(num.length < limit){
while(num.length < limit){
num += '0';
}
}
return num;
}
4 comentários:
Já que se está a lidar com números, para quê manipular strings quando se pode apelar ao Math?
function Precision( num, nDecimals ) {
var i = Math.floor( num );
var f = Math.round( ( num - i ) * Math.pow( 10, nDecimals) );
return i + "." + f;
}
Tens razão uma abordagem tradicional é muito mais simples, o único problema aqui é que o cliente que encomendou isto é um chato de primeira em termos de formatação da string e não consegui manipular a formatação se não encarar o número como uma string no resto do código. Por exemplo um número normal seria 12345.8 o que eles querem que apareça é 12 345,80.
Para além disto ainda tenho de detectar a introdução de pontos ou caracteres não numéricos e remove-los por javascript, uma simples soma nem imaginas as dores de cabeça e as discussões que gerou!!!
Strings SUCK!!! ;-)
Mas mesmo que não fossem preciso todas essas mariquiçes, a minha primeira solução também não dava totalmente conta do recado. Papa os zeros à esquerda da parte decimal.
function precision(n,d) {
function zero_pad (n,l) {
function zeros (n) { var z = ''; for ( i = 0; i < n; ++i ) z += '0'; return z; }
var p = 0;
for ( t = Math.pow(10,l)/10; t >= 1; t /= 10 ) {
if ( 0 == Math.floor(n/t) ) p += 1;
else break;
}
return zeros(p);
}
var i = Math.floor(n);
var f = Math.round((n-i) * Math.pow(10,d));
return i + "." + zero_pad(f,d) + (0 != f ? f : "");
}
é mais facil que parece:
var stringue = (28.674635241).toFixed(2);
Resultado:
#String: 28.67
Enviar um comentário