2011-07-04 18 views
6

Nie wiem, czy jestem brakuje czegoś oczywiste tutaj, ale ...Firefox i JavaScript zasady zaokrąglania

w IE, Opera i Chrome, dostaję to, czego oczekuję od zaokrąglania liczb kończących się na 5:

125 toPrecision(2) => 130 
11.5 toPrecision(2) => 12 

Tego właśnie się spodziewałam.

Firefox, choć jest trochę bardziej „wyrafinowane” uzyskując następujące:

125 toPrecision(2) => 120 //wtf!!! 
11.5 toPrecision(2) => 12 

Po nieco głowę zarysowania, doszedłem do wniosku, że Firefox jest przy pomocy „zaokrąglania nawet” regułę gdzie, jeśli cyfra przed 5 jest nawet liczba rund w dół i jeśli cyfra przed 5 jest nieparzysta liczba rund:

0.5 => 0 
1.5 => 2 
2.5 => 2 
3.5 => 4, etc. 

Używam zaokrąglone wyniki przetestować rozwiązania studentowi pytania inżynierskich z pseudo -nie generowane pytania wejściowe. Wprowadzanie pytania w Chrome może wynosić h = 1020 mm, ale h = 1030 mm w FF, Chrome lub Opera.

Potrzebuję funkcji, aby zaokrąglenie było spójne, tj. Chcę, aby 0,00zaokrąglało do 0,000124 i chcę 1234 zaokrąglić do 1240, więc nie mogę użyć prostej liczby = Math.floor (liczba + 0,5); Aby skomplikować sprawy trochę, chcę zmienne wejściowe i odpowiedzi studentów za prawidłowe do 3 sig wykopalisk chyba pierwsza cyfra to 1, w tym przypadku chcę 4 sig wykopuje:

234.5 => 235 
134.5 => 134.5 

Mam hacked rozwiązanie do 3 lub 4-znakowych cyfr w zależności od pierwszej cyfry poprzez konwersję liczby na ciąg i testowanie pierwszego niezerowego, nieczytelnego punktu i nieujemnego znaku dla "1" - nie jest ładny, ale działa. Mógłbym zrobić coś podobnego do problemu zaokrąglania, sprawdzając, czy cyfra, która ma zostać zaokrąglona, ​​wynosi 5, ale zastanawiam się, czy istnieje eleganckie rozwiązanie oparte na bitach.

+0

"Chcę 1234 zaokrąglić do 1240"? –

Odpowiedz

1

Proszę spojrzeć na testach tutaj

http://yuiblog.com/blog/2009/03/10/when-you-cant-count-on-your-numbers/

JavaScript ma jeden typ numer: IEEE 754 zmiennoprzecinkowych podwójnej precyzji punkt. Posiadanie jednego typu numeru to jedna z najlepszych funkcji JavaScript. Wiele typów liczb może być źródłem złożoności, zamieszania i błędu. Pojedynczy typ jest upraszczający i stabilizuje się w trybie .

Niestety, binarny zmiennoprzecinkowy typ ma pewne znaczące wady: . Najgorsze jest to, że nie może dokładnie reprezentować ułamków dziesiętnych , co jest dużym problemem , ponieważ ludzkość robi handel dziesiętny przez długi, długi czas . Mogłoby to być korzystne dla przełączania na system oparty na liczbie binarnej o numerze , ale to się nie stanie . W konsekwencji 0,1 + 0,2 === 0,3 jest fałszywe, co jest źródłem wielu nieporozumień.

również spojrzeć na SO pytania:

https://stackoverflow.com/questions/287744/good-open-source-javascript-math-library-for-floating-point-operations

i

https://stackoverflow.com/questions/744099/javascript-bigdecimal-library/1575569#1575569

+0

Czy możesz umieścić esencję informacji znajdujących się za linkami w swojej odpowiedzi? W ten sposób informacje pozostaną dostępne, nawet jeśli linki się zestarzeją. –

+0

Tylko pierwsza była zewnętrzna – mplungjan

0

O "Chcę 0.00zaokrąglić w górę do 0.000124": To nie czyni wiele sensu, ponieważ w odróżnieniu od 0,5, 1,5, 2,5 itd., liczba dziesiętna 0,00nie jest dokładnie reprezentowana w radix 2; więc zaokrąglenie może być nieco powyżej (A) lub nieco poniżej (B) dokładnej wartości, gdzie (A) i (B) przyniosłyby różne zaokrąglenia: 0,000124 dla (A), 0,00dla (B).

Nawet jeśli otrzymasz liczbę ułamkową, taką jak 1,5, zaokrągloną do liczby całkowitej po niektórych obliczeniach, (1.5) .toPrecision (2) niekoniecznie będzie dawało wartość, która jest najbliższa dokładnej wartości. Powodem jest to, że dokładna wartość może wynosić nieco poniżej 1,5, w takim przypadku prawidłowe zaokrąglenie wynosi 1, a nie 2. Ten problem jest znany jako dylemat Stolarza.

Oznacza to również, że jeśli dwoje uczniów stosuje nieco inne metody (zarówno dość dokładne), jak i zaokrągla swoje przybliżenia, otrzymają one różne zaokrąglone wyniki (nawet jeśli ich przybliżenia mogą być bardzo bliskie). W przypadku remisu, takiego jak 0,00(z zaokrągleniem do 0,000124), dylemat stołu twórcy jest nieunikniony, chyba że wszystkie obliczenia są przeprowadzane dokładnie lub algorytm specjalnie sprawdza przypadki remisu.

Jednak jeśli dokładny wynik to remis lub bardzo blisko remisu, nadal można sprawdzić, czy uczeń udzielił odpowiedzi (A) lub (B).