2010-01-18 20 views
41

Pomysł mnie uderzył, gdy pisałem fragment kodu JavaScript, który przetwarzał niektóre wartości zmiennoprzecinkowe. Co to jest symbol punktu dziesiętnego w JavaScript? Czy zawsze jest to .? Czy jest to specyficzne dla kultury? A co z .toFixed() i .parseFloat()? Jeśli przetwarzam dane wejściowe użytkownika, najprawdopodobniej uwzględniony zostanie lokalny symbol separatora dziesiętnego specyficzny dla kultury.Jaki jest separator dziesiętny w JavaScript?

Ostatecznie chciałbym napisać kod, który obsługuje zarówno liczbę dziesiętną w danych wejściowych użytkownika - specyficzne dla kultury i ., ale nie mogę napisać takiego kodu, jeśli nie wiem, czego JavaScript oczekuje.

Dodano: OK Rubens Farias suggests patrzeć similar question który ma schludny odpowiedź przyjętych:

function whatDecimalSeparator() { 
    var n = 1.1; 
    n = n.toLocaleString().substring(1, 2); 
    return n; 
} 

To miłe, to pozwala mi uzyskać punkt locale dziesiętny. Krok w stronę rozwiązania, bez wątpienia.

Pozostała część będzie polegała na określeniu zachowania .parseFloat(). Kilka odpowiedzi wskazuje, że dla literałów zmiennoprzecinkowych ważne jest tylko .. Czy .parseFloat() działa w ten sam sposób? A może może wymagać lokalnego separatora dziesiętnego w niektórych przeglądarkach? Czy istnieją również inne metody analizowania liczb zmiennoprzecinkowych? Czy powinienem rozwinąć swoje własne, by być pewnym?

+0

@ Vilx - dla tego, co robisz, rozważam użycie operatora unarnego (+) zamiast 'parseFloat()'. Będzie to znacznie łatwiejsze podczas sprawdzania danych wejściowych. Zobacz moją zaktualizowaną odpowiedź. –

Odpowiedz

19

Według specyfikacja, DecimalLiteral jest zdefiniowana jako:

DecimalLiteral :: 
    DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt 
    . DecimalDigits ExponentPartopt 
    DecimalIntegerLiteral ExponentPartopt 

i dla spełnienia argumentu parseFloat:

  1. Niech inputString będzie ToString (ciąg).
  2. Let trimmedString być podciąg z inputString składający się z lewej znak, który nie jest StrWhiteSpaceChar i wszystkie znaki na prawo od tego znaku. (Innymi słowy, usunąć prowadząc spacje).
  3. Jeśli nie trimmedString ani żaden przedrostek z trimmedString spełnia składnię StrDecimalLiteral (patrz 9.3.1), zwraca NaN.
  4. Niech numberString będzie najdłuższym prefiksem trimmedString, który może być przyciętyString, który spełnia składnię StrDecimalLiteral.
  5. Powrót Wartość liczbowa dla MV

Więc numberString staje najdłuższy prefiks trimmedString który spełnia składnię StrDecimalLiteral, czyli pierwszy parsowalnym dosłownego numer ciągu stwierdzi na wejściu. Tylko . może być użyty do określenia liczby zmiennoprzecinkowej.Jeśli przyjmowanie wejść z różnych lokalizacjach, należy wymienić łańcuch:

function parseLocalNum(num) { 
    return +(num.replace(",", ".")); 
} 

Funkcja korzysta z operatorem, zamiast parseFloat, ponieważ wydaje mi się, że chcesz być surowe o wejściu. parseFloat("1ABC") byłby 1, podczas gdy użycie operatora jednoargumentowego +"1ABC" zwraca NaN. To znacznie ułatwia weryfikację danych wejściowych. Używanie parseFloat polega jedynie na zgadywaniu, że dane wejściowe mają poprawny format.

+0

To jest dla literałów. Czy '.parseFloat()' jest wymagane do zrobienia tego samego? –

+3

Tak. 'parseFloat (" 1,01 ")' w każdym języku zwróci '1', a nie' 1.01' –

+4

Mozilla Developer Center mówi: "parseFloat analizuje swój argument, ciąg znaków i zwraca liczbę zmiennoprzecinkową. Jeśli napotka znak inny niż znak (+ lub -), numer (0-9), kropka dziesiętna lub wykładnik, zwraca wartość do tego punktu i ignoruje ten znak oraz wszystkie kolejne znaki. Dopuszczalne są spacje wiodące i końcowe. " https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/parseFloat –

2

O ile mi wiadomo, javascript sam wie tylko o separatorze . dla miejsc dziesiętnych. Przynajmniej jedna osoba, której orzeczenie Ufam na JS miejscach zgadza:

http://www.merlyn.demon.co.uk/js-maths.htm#DTS

+2

Aby to dodać, zobacz starą specyfikację ECMAScript 262 na temat analizy gramatyki w pisaniu literałów numerycznych: http://bclary.com/2004/11/07/#a-7.8.3 – Anonymous

+0

Ach tak, zawsze dobrze mieć oficjalną dokumentację dla tego typu rzeczy, dzięki :) –

+0

Tak, to dla literałów. A co z parsowaniem ciągów wejściowych? –

9

zastosowanie:

theNumber.toLocaleString(); 

aby uzyskać prawidłowo sformatowany ciąg znaków z prawej przecinku i tysiące separatory

+0

OK. I jak analizować ciąg za pomocą tych separatorów? –

+0

musisz rozebrać sepsy i upewnić się, że jest to zgodne z: [\ + \ -]? ([0-9] + | [0-9] * (\. ([EE] [\ + \ -]? [0-9] +))?) – jspcal

+0

Wystarczająco uczciwe, mogę usunąć wszystko, co jest potrzebne, i zastąpić separator specyficzny dla regionu za pomocą '.'. Ale jest '.' jedyną rzeczą, której oczekuje' .parseFloat() '? –

Powiązane problemy