Perché 0.-5 restituisce -5?


85

Supponiamo che io scriva 0.5come 0.-5in un modo inaspettato, ma può ancora funzionare. Cosa fa 0.in 0.-5modo che possa ancora funzionare e restituisca -5?

Ho anche provato alert(0.-5+1)quali stampe -4, JavaScript ignora 0.in 0.-5?


55
0.è come 0.0. O semplicemente 0.
Ry-

61
Cosa ti fa pensare che 0.-5sia un "modo inaspettato"?
Nico Haase

15
@NicoHaase: Sono abbastanza sicuro che l'OP abbia usato "modo inaspettato" per significare "non intendevo / mi aspettavo di scriverlo, ma in qualche modo l'ho fatto".
Filip Milovanović

15
Funziona anche in molti altri linguaggi (ad esempio Python). Personalmente non mi piace affatto. Preferirei 0.-5essere un errore di sintassi e non consentire i valori letterali float con un punto finale, ma costringere le persone a scrivere .0alla fine.
Giacomo Alzetta

9
È particolarmente negativo perché consentire ai numeri di finire .ti impedisce di scrivere qualcosa del tipo 123.toString(16)(Un trucco comune è usare 123..toString(16), che è davvero (123.).toString(16))
12Me21

Risposte:


191

Le cifre finali dopo la a .sono facoltative:

console.log(0. === 0); // true

Così

0.-5

valuta a

0 - 5

che è giusto -5. Allo stesso modo,

0.-5+1

è

0 - 5 + 1

che è

-5 + 1

o -4.


17
Anche le cifre iniziali sono facoltative, quindi anche .0-5 è valido
icenac

48

0.-5potrebbe essere analizzato con successo come 0.[1] , -e 5. Di seguito è riportato l'albero della sintassi astratta per l'espressione generata da AST explorer:

Parse tree generato da AST explorer

Questo (in modo inaspettato) è JavaScript valido e restituisce -5.


[1] Secondo la grammatica per i letterali numerici, le cifre decimali e le parti esponenti sono opzionali:

NumericLiteral ::
  DecimalLiteral
  [...]

DecimalLiteral ::
  DecimalIntegerLiteral. DecimalDigits opt ExponentPart opt


come hai estratto l'AST?
Κωλζαρ

8
Vai su astexplorer.net , scegli una lingua e un parser, incolla il codice, scegli l'output JSON (o fai uno screenshot).
Salman A

39

In JS puoi esprimere un numero con il punto decimale opzionale.

x = 5.;    //5
x = 5. + 6.   //11

E a partire dal commento di Tvde1, è possibile applicare anche qualsiasi metodo Number.

5..toString()

Questa sintassi ci consente di eseguire le funzioni numeriche senza parentesi.

5.toString() //error
(5).toString() //good
5..toString() //good
5 .toString() // awesome

Vedi questa domanda per scoprire perché.


4
Puoi anche farlo 5..toString().
Tvde1

2
In effetti, devi fare 5..toString () per chiamare il metodo, altrimenti devi usare le parentesi: (5) .toString ()
jo_va

3
@PeterMortensen Ruby, per esempio. Anche ALGOL 68. In Common Lisp, stranamente, 1.0è in virgola mobile ma 1.è un numero intero.
Sneftel

2
@FlorianF Non lo faresti, ma ciò non significa che il parser debba essere in un caso speciale per rifiutarlo. floatha metodi ed 5.è un file float.
chepner

2
@MasonWheeler E 'certamente non è il caso che qualsiasi altra lingua in cui (1).toMethod()è legale vieta (1.)dal parsing correttamente. L'approccio più tradizionale all'analisi (lexing avido dei token, inclusi i letterali, quindi l'analisi) produce il comportamento Javascript.
Sneftel

7

Penso che la vera risposta non sia sul punto decimale, ma sul segno meno: non sarà interpretato come un operatore se è preceduto da qualcosa che assomiglia a un numero?


1
Quindi, almeno da un certo punto di vista, si tratta ancora di interpretare il punto decimale come parte di un numero letterale, altrimenti ciò che precede il segno meno non "sembra un numero".
Pac0

5

console.log(0. - 5)      // -5
console.log(0 - 5)       // -5
console.log('0.' - 5)    // -5
console.log('0' - 5)     // -5
console.log(0.-5 === -5) // true

"0." o "0" è lo stesso in JavaScript perché il tipo è univoco per i numeri, chiamato Numero. L'operatore meno è tra i numeri, cerca sempre di convertire ciò che passi in un numero. In Python è diverso il primo è un Float e il secondo un Integer perché ha diversi tipi.


Questo problema non è correlato ai tipi; è solo correlato alla sintassi.
Sebastian Simon
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.