W JavaScripcie, jak przekonwertować zmiennoprzecinkowe na ciąg, w jaki sposób mogę uzyskać tylko 2 cyfry po przecinku? Na przykład 0,34 zamiast 0,3445434.
W JavaScripcie, jak przekonwertować zmiennoprzecinkowe na ciąg, w jaki sposób mogę uzyskać tylko 2 cyfry po przecinku? Na przykład 0,34 zamiast 0,3445434.
Odpowiedzi:
var result = Math.round(original*100)/100;
Szczegóły , w przypadku gdy kod nie jest zrozumiały.
edytuj: ... lub po prostu użyj toFixed
, jak zaproponował Tim Büthe . Zapomniałem tego, dziękuję (i głosowanie) za przypomnienie :)
toFixed()
naśladuje to, co printf()
robi coś w C. Jednak toFixed()
i Math.round()
zaokrągla inaczej. W takim przypadku toFixed()
będzie miał taki sam efekt Math.floor()
, jaki miałbyś (zakładając, że wcześniej pomnożono oryginał przez 10 ^ n i dzwonisz za toFixed()
pomocą n cyfr). „Poprawność” odpowiedzi jest bardzo zależna od tego, czego chce tu PO, i oba są „poprawne” na swój sposób.
Istnieją funkcje zaokrąglania liczb. Na przykład:
var x = 5.0364342423;
print(x.toFixed(2));
wydrukuje 5.04.
EDYTOWAĆ: Skrzypce
var x = 5.036432346; var y = x.toFixed(2) + 100;
y
będzie równy"5.03100"
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
…
Zachowaj ostrożność, używając toFixed()
:
Po pierwsze, zaokrąglanie liczby odbywa się za pomocą binarnej reprezentacji liczby, co może prowadzić do nieoczekiwanego zachowania. Na przykład
(0.595).toFixed(2) === '0.59'
zamiast '0.6'
.
Po drugie, występuje błąd IE toFixed()
. W IE (przynajmniej do wersji 7 nie sprawdzono IE8) spełnione są następujące warunki:
(0.9).toFixed(0) === '0'
Dobrym pomysłem może być skorzystanie z sugestii kkyy lub użycie niestandardowej toFixed()
funkcji, np
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
.toFixed()
metody natywnej do wartości zwracanej, która doda wymaganą dokładność, np .: return (Math.round(value * power) / power).toFixed(precision);
a także zwróci wartość jako ciąg znaków. W przeciwnym razie precyzja 20 jest ignorowana dla mniejszych miejsc po przecinku
toFixed
: zauważ, że zwiększenie precyzji może przynieść nieoczekiwane rezultaty: (1.2).toFixed(16) === "1.2000000000000000"
podczas gdy (1.2).toFixed(17) === "1.19999999999999996"
(w Firefox / Chrome; w IE8 ta ostatnia nie działa z powodu niższej precyzji, którą IE8 może zaoferować wewnętrznie).
(0.598).toFixed(2)
nie produkuje 0.6
. Produkuje 0.60
:)
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
.
Kolejnym problemem, o którym należy pamiętać, jest to, że toFixed()
może generować niepotrzebne zera na końcu liczby. Na przykład:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
Chodzi o to, aby wyczyścić dane wyjściowe za pomocą RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
RegExp
Dopasowuje zer (i opcjonalnie przecinek), aby upewnić się, że wygląda dobrze dla liczb całkowitych, jak również.
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
Problem polega na tym, że wszystkie te rozwiązania zmieniają się przy użyciu mnożników. Rozwiązania zarówno Kkyy, jak i Christopha są niestety błędne.
Sprawdź kod pod kątem liczby 551.175 z 2 miejscami po przecinku - zaokrągli on do 551.17, a powinien mieć 551,18 ! Ale jeśli testujesz na ex. 451,175 wszystko będzie dobrze - 451,18. Dlatego trudno jest zauważyć ten błąd na pierwszy rzut oka.
Problem polega na pomnożeniu: spróbuj 551,175 * 100 = 55117.49999999999 (ups!)
Więc moim pomysłem jest potraktowanie go za pomocą toFixed () przed użyciem Math.round ();
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
toFixed
to również wpływa - (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
… Bez względu na zastosowaną metodę, lepiej dodać epsilon przed zaokrągleniem.
Wydaje mi się, że kluczem jest prawidłowe zaokrąglenie w górę, a następnie konwersja do String.
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
Teraz możesz bezpiecznie sformatować tę wartość za pomocą toFixed (p). W przypadku konkretnego przypadku:
roundOf(0.3445434, 2).toFixed(2); // 0.34
Jeśli chcesz ciąg bez rundy, możesz użyć tego RegEx (może nie jest to najbardziej wydajny sposób ... ale jest naprawdę łatwy)
(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;
inaczej jeśli przeszedł całkowitą, to zwrócony liczby z kropką na końcu (na przykład wejście: 2100
, moc: 2100.
)
Może chcesz też separator dziesiętny? Oto funkcja, którą właśnie stworzyłem:
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;
}
Nie ma sposobu, aby uniknąć niespójnego zaokrąglania cen z wartością x.xx5 jako wartością rzeczywistą za pomocą mnożenia lub dzielenia. Jeśli musisz obliczyć prawidłowe ceny po stronie klienta, powinieneś zachować wszystkie kwoty w centach. Wynika to z natury wewnętrznej reprezentacji wartości liczbowych w JavaScript. Zauważ, że Excel ma te same problemy, więc większość ludzi nie zauważy małych błędów spowodowanych tym zjawiskiem. Jednak błędy mogą się kumulować, ilekroć dodasz dużo obliczonych wartości, istnieje cała teoria obejmująca kolejność obliczeń i inne metody, aby zminimalizować błąd w wyniku końcowym. Aby podkreślić problemy z wartościami dziesiętnymi, należy pamiętać, że 0,1 + 0,2 nie jest dokładnie równe 0,3 w JavaScript, podczas gdy 1 + 2 jest równe 3.
/** 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"
Używam tego kodu do formatowania liczb zmiennoprzecinkowych. Opiera się na, toPrecision()
ale usuwa niepotrzebne zera. Z zadowoleniem przyjmuję sugestie dotyczące uproszczenia wyrażenia regularnego.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Przykład użycia:
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>');