Yanıtlar:
var result = Math.round(original*100)/100;
Özelliklerini , durumda kod kendini açıklayıcı değildir.
edit: ... ya da sadece kullanın toFixed
, Tim Büthe tarafından önerildiği gibi . Bunu unuttum, hatırlatma için teşekkürler (ve bir yukarı oy) :)
toFixed()
printf()
Ancak C'de nasıl bir şey olduğunu taklit eder toFixed()
ve Math.round()
yuvarlamayı farklı şekilde ele alır. Bu durumda, toFixed()
aynı tür bir etkiye sahip Math.floor()
olacaktır (orijinali önceden 10 ^ n ile çarptığınız ve toFixed()
n basamakla çağırdığınız kabul edilir). Cevabın "doğruluğu" OP'nin burada ne istediğine çok bağlıdır ve her ikisi de kendi yollarıyla "doğrudur".
Sayıları yuvarlamak için işlevler vardır. Örneğin:
var x = 5.0364342423;
print(x.toFixed(2));
5.04 yazdıracaktır.
DÜZENLEME: Keman
var x = 5.036432346; var y = x.toFixed(2) + 100;
y
eşit olacak"5.03100"
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
…
Kullanırken dikkatli olun toFixed()
:
İlk olarak, sayının yuvarlanması, sayının ikili gösterimi kullanılarak yapılır, bu da beklenmedik davranışlara yol açabilir. Örneğin
(0.595).toFixed(2) === '0.59'
yerine '0.6'
.
İkincisi, bir IE hatası var toFixed()
. IE'de (en azından sürüm 7, IE8'i kontrol etmedi), aşağıdakiler geçerlidir:
(0.9).toFixed(0) === '0'
Kkyy'nin önerisini takip etmek veya özel bir toFixed()
işlev kullanmak iyi bir fikir olabilir , örn.
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
.toFixed()
gerekli değer, örneğin ekleyecek dönüş değeri, yerel yöntem ekleme öneririz : return (Math.round(value * power) / power).toFixed(precision);
ve ayrıca değeri bir dize olarak döndürür. Aksi takdirde, daha küçük ondalık sayılar için 20'nin hassasiyeti yok sayılır
toFixed
: hassasiyet artan beklenmeyen sonuçlara yol açabilir o notu (1.2).toFixed(16) === "1.2000000000000000"
iken (1.2).toFixed(17) === "1.19999999999999996"
(Firefox / Chrome'da; IE8'de ikincisi IE8 içten sunabileceği hassas düşmesi nedeniyle tutmadığı).
(0.598).toFixed(2)
üretmez 0.6
. Ürettiği 0.60
:)
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
.
Dikkat edilmesi gereken bir başka sorun da toFixed()
, sayının sonunda gereksiz sıfırlar üretebilmesidir. Örneğin:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
Fikir, çıktıyı aşağıdakileri kullanarak temizlemektir RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
RegExp
Emin tamsayılar için iyi yanı görünüyor yapmak için sondaki sıfırları (ve isteğe ondalık noktayı) eşleşir.
humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding
Bu çözümlerin çarpanları kullanarak yüzdüğü bir sorun var. Hem kkyy hem de Christoph'un çözümleri ne yazık ki yanlış.
Lütfen kodunuzu 2 ondalık basamakla 551.175 sayısı için test edin - 551.18 olması gerekirken 551.17'ye yuvarlanır ! Ama eski için test ederseniz. 451.175 iyi olacak - 451.18. Bu yüzden bu hatayı ilk bakışta tespit etmek zor.
Sorun çarpmayla ilgili: 551.175 * 100 = 55117.49999999999 (ups!)
Benim fikrim Math.round () kullanmadan önce toFixed () ile tedavi etmek;
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
toFixed
de etkilenir - (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
… Hangi yöntem kullanılırsa kullanılsın, yuvarlamadan önce bir epsilon ekleyin.
Buradaki anahtar, önce doğru şekilde yuvarlamaktır, daha sonra String'e dönüştürebilirsiniz.
function roundOf(n, p) {
const n1 = n * Math.pow(10, p + 1);
const n2 = Math.floor(n1 / 10);
if (n1 >= (n2 * 10 + 5)) {
return (n2 + 1) / Math.pow(10, p);
}
return n2 / Math.pow(10, p);
}
// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34
Artık bu değeri toFixed (p) ile güvenle biçimlendirebilirsiniz. Yani özel durumunuzla:
roundOf(0.3445434, 2).toFixed(2); // 0.34
Dize tur olmadan istiyorsanız bu RegEx'i kullanabilirsiniz (belki de en etkili yol değildir ... ama gerçekten kolaydır)
(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'
function trimNumber(num, len) {
const modulu_one = 1;
const start_numbers_float=2;
var int_part = Math.trunc(num);
var float_part = String(num % modulu_one);
float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
return int_part+'.'+float_part;
}
return float_part ? int_part+'.'+float_part : int_part;
Eğer Tamsayı geçti aksi takdirde, bu sonunda bir nokta ile sayı döndürdü (örnek girişi: 2100
, çıkış: 2100.
)
Belki de ondalık ayırıcı isteyeceksiniz? İşte yeni yaptığım bir fonksiyon:
function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
if (num < 0)
{
num = -num;
sinal = -1;
} else
sinal = 1;
var resposta = "";
var part = "";
if (num != Math.floor(num)) // decimal values present
{
part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
while (part.length < casasDec)
part = '0'+part;
if (casasDec > 0)
{
resposta = sepDecimal+part;
num = Math.floor(num);
} else
num = Math.round(num);
} // end of decimal part
while (num > 0) // integer part
{
part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
num = Math.floor(num/1000);
if (num > 0)
while (part.length < 3) // 123.023.123 if sepMilhar = '.'
part = '0'+part; // 023
resposta = part+resposta;
if (num > 0)
resposta = sepMilhar+resposta;
}
if (sinal < 0)
resposta = '-'+resposta;
return resposta;
}
X.xx5 olan fiyatların çarpma veya bölme kullanarak gerçek değer olarak tutarsız yuvarlanmasından kaçınmanın bir yolu yoktur. Müşteri tarafında doğru fiyatları hesaplamanız gerekiyorsa, tüm miktarları sent cinsinden tutmalısınız. Bu, JavaScript'teki sayısal değerlerin dahili sunumunun doğasından kaynaklanmaktadır. Excel'in aynı sorunlardan muzdarip olduğuna dikkat edin, bu yüzden çoğu insan bu fenomenin neden olduğu küçük hataları fark etmeyecektir. Bununla birlikte, çok sayıda hesaplanmış değer eklediğinizde hatalar birikebilir, bunun etrafında hesaplamaların sırasını ve nihai sonuçtaki hatayı en aza indirmek için diğer yöntemleri içeren bir teori vardır. Ondalık değerlerle ilgili sorunları vurgulamak için, JavaScript'te 0,1 + 0,2'nin tam olarak 0,3'e eşit olduğunu, 1 + 2'nin 3'e eşit olduğunu lütfen unutmayın.
/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) {
if (!nbDec) nbDec = 100;
var a = Math.abs(x);
var e = Math.floor(a);
var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
var signStr = (x<0) ? "-" : " ";
var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
var eStr = e.toString();
return signStr+eStr+"."+decStr;
}
prettyFloat(0); // "0.00"
prettyFloat(-1); // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5); // "0.50"
Bu kodu yüzen biçimlendirmek için kullanın. Tabanlı toPrecision()
ama gereksiz sıfırlar çıkarıyor. Normal ifadeyi basitleştirmek için önerilerinizi memnuniyetle karşılarım.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Kullanım örneği:
function test(x, n, d) {
var rounded = rnd(x, d);
var result = rounded.toPrecision(n);
result = result.replace(/\.?0*$/, '');
result = result.replace(/\.?0*e/, 'e');
result = result.replace('e+', 'e');
return result;
}
document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');