Burada bir şey mi eksik?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Neden gelmez.toFixed()
bir dize döndürür?
Sayıyı 2 ondalık basamağa yuvarlamak istiyorum.
Burada bir şey mi eksik?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Neden gelmez.toFixed()
bir dize döndürür?
Sayıyı 2 ondalık basamağa yuvarlamak istiyorum.
Yanıtlar:
Bir dize döndürür, çünkü 0.1 ve güçleri (ondalık kesirleri görüntülemek için kullanılır), ikili kayan noktalı sistemlerde temsil edilemez (en azından tam doğrulukla değil).
Örneğin, 0.1 gerçekten 0.1000000000000000055511151231257827021181583404541015625 ve 0.01 gerçekten 0.01000000000000000020816681711721685132943093776702880859375. (Demek istediğimi BigDecimal
kanıtladığın için teşekkürler . :-P)
Bu nedenle (ondalık kayan nokta veya rasyonel sayı türü olmadığında), dize olarak çıktı almak, görüntüleme için gereken hassasiyete göre kesilmesinin tek yoludur.
toFixed
sadece bir sayıyı bir dizeye dönüştürmek, belirtilen ondalık sayıları kullanarak biçimlendirmek olan bir biçimlendirme işlevidir. Bir dize döndürmesinin nedeni, bir dize döndürmesi gerektiğidir ve toStringFixed
bunun yerine adlandırılırsa , OP sonuçlara şaşırmaz. Buradaki tek sorun OP'nin Math.round
JS referansına başvurmadan çalışmasını beklemesidir .
Number.prototype.toFixed
bir sayıyı yazdırmadan önce biçimlendirmek için tasarlanmış bir işlevdir . Bu bir aileden geliyor toString
, toExponential
ve toPrecision
.
Bir sayıyı yuvarlamak için bunu yaparsınız:
someNumber = 42.008;
someNumber = Math.round( someNumber * 1e2 ) / 1e2;
someNumber === 42.01;
// if you need 3 digits, replace 1e2 with 1e3 etc.
// or just copypaste this function to your code:
function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}
.
Veya " yerel benzeri " bir işlev istiyorsanız, prototipi genişletebilirsiniz:
Number.prototype.toFixedNumber = function(digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(this*pow) / pow;
}
someNumber = 42.008;
someNumber = someNumber.toFixedNumber(2);
someNumber === 42.01;
//or even hexadecimal
someNumber = 0xAF309/256 //which is af3.09
someNumber = someNumber.toFixedNumber(1, 16);
someNumber.toString(16) === "af3.1";
Bununla birlikte , modül yazarken prototipi kirletmenin kötü kabul edildiğini unutmayın, çünkü modüllerin herhangi bir yan etkisi olmamalıdır. Bu nedenle, bir modül için ilk işlevi kullanın .
type Number
. Mesele şu ki, +(anyValue)
her zaman bir sayı döndürür - örn. +("45")
döner 45
, +(new Number(42))
döner 42
. Bu güçlü yazma fonksiyonu gibi. Eğer bir alışkanlık yaparsanız, bir çok hata önleyebilirsiniz :)
someNumber = Math.round( 42.008 * 1e2 ) / 1e2;
değil 42.01
, öyle ~42.0099999999999980
. Sebep: Sayı 42.01
mevcut değil ve mevcut en yakın sayıya yuvarlanıyor. btw, toPrecision(18)
ilgili tüm rakamlarla yazdırmak için rakamları onaylayın.
Bunu değiştirerek bu sorunu çözdüm:
someNumber = someNumber.toFixed(2)
...buna:
someNumber = +someNumber.toFixed(2);
Bununla birlikte, bu sayı bir dizgiye dönüştürülür ve tekrar ayrıştırılır, bu da performans üzerinde önemli bir etkisi olacaktır. Performans veya tip güvenliği ile ilgileniyorsanız, diğer cevapları da kontrol edin.
someNumber = Math.round(someNumber * 1e2) / 1e2
! Daha genel bir yol için cevabımı görün.
Neden kullanmıyorsunuz parseFloat
?
var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
Tabii ki bir dize döndürür. Sayısal değişkeni yuvarlamak isterseniz bunun yerine Math.round () yöntemini kullanırsınız. ToFixed, sayıyı kullanıcıya gösterilecek sabit sayıda ondalık basamakla biçimlendirmektir .
Bir sayıyı biçimlendirmesi gerektiğinde ne dönmesini beklersiniz? Eğer bir numaranız varsa, onunla bir şey yapamazsınız çünkü örneğin 2 == 2.0 == 2.00
vb.
Neden dize olması gerektiğine ilişkin bir örnek vermek için:
1.toFixed (2) 'yi biçimlendirirseniz' 1.00 'alırsınız.
Bu 1 ile aynı değildir, çünkü 1'de 2 ondalık sayı yoktur.
JavaScript'in tam olarak bir performans dili olmadığını biliyorum , ancak böyle bir şey kullanırsanız bir yuvarlama için daha iyi performans elde edersiniz: roundedValue = Math.round (değer * 100) * 0.01
Birincil kullanımı sayıları gösterdiği için mi? Sayıları yuvarlamak istiyorsanız, Math.round()
uygun faktörlerle kullanın .
'42'
bir sayı olduğu gibi ... öyle değil. Bir dizenin yalnızca rakam içerdiği için onu bir sayı yapmaz. Bu PHP değil. :-P
İşte verilen cevabın biraz daha işlevsel bir versiyonu m93a
.
const toFixedNumber = (toFixTo = 2, base = 10) => num => {
const pow = Math.pow(base, toFixTo)
return +(Math.round(num * pow) / pow)
}
const oneNumber = 10.12323223
const result1 = toFixedNumber(2)(oneNumber) // 10.12
const result2 = toFixedNumber(3)(oneNumber) // 10.123
// or using pipeline-operator
const result3 = oneNumber |> toFixedNumber(2) // 10.12