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; }
Já que se está a lidar com números, para quê manipular strings quando se pode apelar ao Math?
ResponderEliminarfunction 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.
ResponderEliminarPara 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!!! ;-)
ResponderEliminarMas 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:
ResponderEliminarvar stringue = (28.674635241).toFixed(2);
Resultado:
#String: 28.67