2011-06-22 17 views
6

Mam pewne problemy ze sposobem, w jaki PHP i javascript zaokrągla liczby. Używam okrągły funkcję PHP i tę funkcję javascript:JavaScript VS zaokrąglanie PHP

function roundNumber(number, decimals) {  
    var newnumber = new Number(number+'').toFixed(parseInt(decimals)); 
    var value = parseFloat(newnumber); 
    return value; 
} 

Liczba próbuję runda 43.65 * 2,5 + 40%, co kiedy odbywa się za pomocą kalkulatora = 152,775 lub po zaokrągleniu w PHP = 152.78.

w JavaScript, gdy robię console.log liczba jest +152,774999999998 i po zaokrągleniu z powyższej funkcji daje mi 152,77

Każda pomoc do reslove ten problem jest bardzo ceniona

+1

To dlaczego nie używać liczb zmiennoprzecinkowych na waluty. –

+0

http://stackoverflow.com/questions/5490687/broken-tofixed-implementation – mplungjan

+0

Upewnij się, że używasz 'parseInt', który określasz podstawnik; zwykle chcesz pracować w bazie 10, więc: 'parseInt (yourNumber, 10)'. – nnnnnn

Odpowiedz

2

Proszę spojrzeć na How to deal with floating point number precision in JavaScript?

Oto przykład

function roundNumber(number, decimals) { 
 
    decimals = parseInt(decimals,10); 
 
    var dec = Math.pow(10,decimals) 
 
    console.log(dec,parseFloat(number)*dec); 
 
    number=""+Math.round(parseFloat(number)*dec+.0000000000001); // fixed the .X99999999999 
 
    return parseFloat(number.slice(0,-1*decimals) + "." + number.slice(-1*decimals))  
 
} 
 

 

 
var val = 43.65 * 2.5; 
 
    val+= val*0.40 
 

 
console.log(val+' ~= 152.78? --> '+roundNumber(val,2).toFixed(2)); 
 
console.log('15.803 ~= 15.80? --> '+roundNumber(15.803,2).toFixed(2)); 
 
console.log('15.805 ~= 15.81? --> '+roundNumber(15.805,2).toFixed(2)); 
 
console.log('14.803 ~= 14.80? --> '+roundNumber(14.803,2).toFixed(2)); 
 
console.log('0.575 ~= 0.58? --> '+roundNumber(0.575,2).toFixed(2));

+0

kończy się niepowodzeniem z 15.803, daje 15.81, a powinno dać 15,80 – max4ever

+0

dzięki. Działa, jeśli zrobię prostą rundę. Zobacz aktualizacje – mplungjan

+0

Działa dla 25,575 (=> 25,58), ale kończy się niepowodzeniem dla 0,575 (=> 0,57) – modernzombie

5

To nie ma nic do zaokrąglić per se, ale ma to związek z tym, jak liczby dziesiętne są reprezentowane w sprzęcie binarnym.

Zapoznaj się z floating point guide, aby uzyskać więcej informacji na ten temat, a także rozwiązania/alternatywy.

1

rundy php do 152,78, ponieważ widzi 152,7749, czyli 152,775, a na końcu 152,178. nie możesz użyć wartości zaokrąglonej z php?

-1

Poniżej znajdują funkcji JavaScript dla formatu liczbowego

<script type="text/javascript"> 
function format_number(pnumber,decimals){ 
    if (isNaN(pnumber)) { return 0}; 
    if (pnumber=='') { return 0}; 

    var snum = new String(pnumber); 
    var sec = snum.split('.'); 
    var whole = parseFloat(sec[0]); 
    var result = ''; 

    if(sec.length > 1){ 
     var dec = new String(sec[1]); 
     dec = String(parseFloat(sec[1])/Math.pow(10,(dec.length - decimals))); 
     dec = String(whole + Math.round(parseFloat(dec))/Math.pow(10,decimals)); 
     var dot = dec.indexOf('.'); 
     if(dot == -1){ 
      dec += '.'; 
      dot = dec.indexOf('.'); 
     } 
     while(dec.length <= dot + decimals) { dec += '0'; } 
     result = dec; 
    } else{ 
     var dot; 
     var dec = new String(whole); 
     dec += '.'; 
     dot = dec.indexOf('.'); 
     while(dec.length <= dot + decimals) { dec += '0'; } 
     result = dec; 
    } 
    return result; 
} 

var value = format_number(newnumber,2); 
</script> 
+1

To wydaje się nieco przesadzone - i uważam, że w złej formie nie przypisuje się, skąd je wziąłeś. http: //www.codingforums.com/archive/index.php/t-190997.html – mplungjan

1

To dlatego, że różni dokładność u sed w JS (przez przeglądarkę) i PHP lub faktycznie ile bitów jest używanych do przechowywania liczb.

można dokonać JS funkcji zaokrąglaniu to zrobić rundę do 2 cyfry Math.round(floatNumber*100)/100

3

myślałem trochę o tym i chciałem podzielić się moją rozwiązanie, niech nie to zmarnować:

function roundNumber(number, decimals) {  
    var d = parseInt(decimals,10), 
     dx = Math.pow(10,d), 
     n = parseFloat(number), 
     f = Math.round(Math.round(n * dx * 10)/10)/dx; 
    return f.toFixed(d); 
} 

Nie korzysta z funkcji ciągów ani żadnych wymuszonych zaokrągleń w górę lub w dół.

przetestować go tutaj: http://jsfiddle.net/inti/hMrsp/4/

Edit: skorygowana została wycinanie zer na końcu

+0

Błąd w var v = 152.79499999999998; - traci ciąg dalszy 0 – mplungjan

+0

@mplungjan Poprawiono. – aorcsik

+0

dziękuję koleś, z jakiegoś powodu ten działa ze wszystkim, podczas gdy wersja mplungjan zawiedzie na przykład na 14.803 – max4ever