2010-01-18 17 views
41

Un pensiero mi colpì mentre stavo scrivendo un pezzo di codice JavaScript che elaborava alcuni valori in virgola mobile. Qual è il simbolo del punto decimale in JavaScript? È sempre .? O è specifico della cultura? E che dire di .toFixed() e .parseFloat()? Se sto elaborando un input utente, è probabile che includa il simbolo del separatore decimale specifico per la cultura locale.Qual è il simbolo del separatore decimale in JavaScript?

In definitiva mi piacerebbe scrivere un codice che supporti entrambi i punti decimali nell'input dell'utente - specifico della cultura e ., ma non posso scrivere un codice del genere se non so cosa si aspetta JavaScript.

Aggiunto: OK, Rubens Farias suggests da guardare similar question che ha una risposta accettata pulito:

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

Che bello, che mi permette di ottenere il punto locale decimale. Un passo verso la soluzione, senza dubbio.

Ora, la parte rimanente sarebbe determinare quale sia il comportamento di .parseFloat(). Diverse risposte sottolineano che per i letterali in virgola mobile è valido solo lo .. .parseFloat() funziona allo stesso modo? O potrebbe richiedere il separatore decimale locale in alcuni browser? Esistono metodi diversi per l'analisi dei numeri in virgola mobile? Devo tirare fuori il mio da solo per essere sicuro?

+0

@ Vilx- per quello che stai facendo, prenderei in considerazione l'uso dell'operatore unario (+) invece di 'parseFloat()'. Sarà molto più semplice quando si convalida l'input. Vedi la mia risposta aggiornata. –

risposta

19

Secondo la specifica, un DecimalLiteral è definito come:

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

e per soddisfare l'argomento parseFloat:

  1. Let InputString essere ToString (stringa).
  2. Sia trimmedString essere una stringa di inputString costituito dal carattere più a sinistra che non è uno StrWhiteSpaceChar e tutti i caratteri a destra di quel personaggio. (In altre parole, rimuovere spazi bianchi.)
  3. Se né trimmedString né alcun prefisso di trimmedString soddisfa la sintassi di StrDecimalLiteral (si veda 9.3.1), restituisce NaN.
  4. Lascia che numberString sia il prefisso più lungo di trimmedString, che potrebbe essere trimmedString stesso, che soddisfi la sintassi di StrDecimalLiteral.
  5. Ritorna il valore numero per la MV

Così numberString diventa il prefisso più lungo di trimmedString che soddisfa la sintassi di uno StrDecimalLiteral, cioè il primo numero stringa letterale parseable si trova in ingresso. È possibile utilizzare solo lo . per specificare un numero in virgola mobile.Se stai accettare input da diversi locali, utilizzare una stringa sostituire:

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

La funzione utilizza l'operatore unario invece di parseFloat perché mi sembra che si vuole essere rigorosi su l'ingresso. parseFloat("1ABC") sarebbe 1, mentre utilizzando l'operatore unario +"1ABC" restituisce NaN. Ciò rende MOLTO più facile convalidare l'input. L'uso di parseFloat sta solo supponendo che l'input sia nel formato corretto.

+0

Questo è per i letterali. '.parseFloat()' richiede di fare lo stesso? –

+3

Sì. 'parseFloat (" 1,01 ")' in qualsiasi locale restituirà '1', non' 1.01' –

+4

Mozilla Developer Center dice: "parseFloat analizza il suo argomento, una stringa, e restituisce un numero in virgola mobile. a parte un segno (+ o -), un numero (0-9), un punto decimale o un esponente, restituisce il valore fino a quel punto e ignora quel carattere e tutti i caratteri successivi. Gli spazi iniziali e finali sono consentiti. " https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/parseFloat –

2

Per quanto ne so, javascript stesso conosce solo il separatore . per i decimali. Almeno una persona il cui giudizio mi fido su JS cose concorda:

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

+2

Per aggiungere a questo, vedere la vecchia specifica ECMAScript 262 su grammatica che analizza i valori letterali numerici: http://bclary.com/2004/11/07/#a-7.8.3 – Anonymous

+0

Ah sì, sempre bene avere documentazione ufficiale per questo genere di cose, grazie :) –

+0

Sì, è per i letterali. Che dire dell'analisi dell'input di stringa? –

9

uso:

theNumber.toLocaleString(); 

per ottenere una stringa formattata correttamente con la virgola a destra e separatori delle migliaia

+0

OK. E come analizzo una stringa con questi separatori? –

+0

avresti bisogno di togliere il seps e assicurarti che sia conforme a qualcosa del tipo: [\ + \ -]? ([0-9] + | [0-9] * (\. ([EE] [\ + \ -]? [0-9] +))?) – jspcal

+0

Abbastanza corretto, posso rimuovere tutto ciò che è necessario e sostituire il separatore specifico della locale con '.'. Ma è '. 'L'unica cosa che' .parseFloat() 'si aspetta? –

Problemi correlati