Esiste un linguaggio di programmazione in cui 1/6 si comporta come 1.0 / 6.0?

11

Mentre stavo programmando in C ++ qualche giorno fa, ho commesso questo errore (che ho una storia di successo!). In una parte del mio codice, avevo 1/6 e mi aspettavo che fosse 0.16666666666 che non è il caso. Come tutti sapete, il risultato è 0 - C, C ++, Java, Python, tutti si comportano allo stesso modo.

Lo postò sulla mia pagina Facebook e ora è in discussione se esiste un linguaggio di programmazione in cui 1/6 si comporta come 1.0/6.0 .

    
posta Pouya 09.08.2012 - 10:03
fonte

13 risposte

17

Tutti hanno dimenticato Pascal?

1/6 produce 0.1666666... (a qualsiasi precisione è supportata).

1 div 6 produce 0

È discutibile se la regola C sia un errore. Quasi tutti gli operatori aritmetici di C, in cui gli operandi sono dello stesso tipo, producono un risultato dello stesso tipo. C'è qualcosa da dire per coerenza.

Inoltre, poiché C è principalmente mirato al codice a livello di sistema, la maggior parte dei programmi C non usa affatto il floating-point. Un tempo, aggiungere accidentalmente un codice in virgola mobile a un programma che altrimenti non avrebbe avuto bisogno potrebbe essere un problema serio. Questo è probabilmente ancora il caso, per i piccoli sistemi embedded, che, ancora una volta, sono un obiettivo importante per C.

Nella maggior parte dei programmi C, troncare la divisione di interi è probabilmente solo quello che vuoi comunque.

Se 1 / 6 ha prodotto un risultato a virgola mobile in C, quindi:

  • Sarebbe un'incongruenza nella lingua.
  • Lo standard dovrebbe fare una scelta arbitraria di tipo quale a virgola mobile da utilizzare per il risultato ( double può sembrare la scelta naturale, ma potresti preferire la precisione extra di long double )
  • La lingua ancora deve avere un'operazione per la divisione di interi; eseguire l'aggiunta a virgola mobile e quindi troncare probabilmente non sarebbe sufficiente.

C potrebbe aver fornito operatori separati per i due tipi di divisione, ma il secondo punto sopra sarebbe ancora valido: quale dei tre tipi a virgola mobile verrebbe utilizzato per il risultato? E poiché è abbastanza facile ottenere una divisione in virgola mobile se ne hai bisogno (usa una costante a virgola mobile per uno o entrambi gli operandi, o lancia uno o entrambi gli operandi su un tipo a virgola mobile), apparentemente non era t considerato importante.

Nella versione del 1974 del manuale C (che è 4 anni prima della pubblicazione della prima edizione di K & R), Ritchie non menziona nemmeno l'eventuale confusione:

The binary / operator indicates division. The same type considerations as for multiplication apply

che dice che se entrambi gli operandi sono di tipo int o char , il risultato è di tipo int .

Sì, è una fonte di confusione per alcuni programmatori C, specialmente per i principianti, ma C non è noto per essere molto amichevole ai novizi.

    
risposta data 09.08.2012 - 19:41
fonte
16

In realtà questo comportamento è stato modificato in Python 3 e ora si comporta come ci si aspetta ( // è ora utilizzato per la divisione in interi).

    
risposta data 09.08.2012 - 10:10
fonte
13

Fuori dalle lingue importanti, JavaScript. 1.0 / 6.0 = 1/6 = ,16666666666666666.

Non lo vedo come sorprendente. Come regola del pollice, se una lingua distingue tra tipi numerici interi e virgola mobile, la divisione di due numeri interi produrrà un numero intero troncato anziché float. In caso contrario, molto probabilmente si imposterà automaticamente su operazioni in virgola mobile. Questo dovrebbe essere il comportamento previsto per la parte del programmatore.

Ricorda che ci sono altre cose che potrebbero anche essere in gioco qui, come il già citato operatore di divisione intero o il tipo implicito di casting.

    
risposta data 09.08.2012 - 17:41
fonte
7

Ci sono molte lingue in cui ((1/6)*6) risulta in 1, non in 0. Ad esempio, PL / SQL, molti dialetti BASIC, Lua.

Accidentalmente, in tutti quei langauges 1/6 risulta in .166666667, o 0.16666666666667 o qualcosa di simile. Ho scelto la ((1/6) * 6) == 1 variante per eliminare quelle piccole differenze.

    
risposta data 09.08.2012 - 10:12
fonte
3

Haskell tratta 1/6 e 1.0 / 6.0 come identicamente 0.16666666666666666. Rende anche 1 / 6.0 e 1.0 / 6 come lo stesso valore.

Questo è dovuto al fatto che i tipi numerici di base in Haskell non sono gli stessi di altre lingue. La vera divisione dei numeri interi è in qualche modo ... complicata.

    
risposta data 09.08.2012 - 20:02
fonte
2

Sì, Perl sì. Il one-liner

perl -e '$x=1/6;print "$x\n";'

produce l'output di:

0.166666666666667

Credo che PHP funzioni allo stesso modo.

Modificato per aggiungere: Credo anche che una condizione necessaria (ma non sufficiente) per 1/6 == 1.0/6.0 sia che la lingua in questione sia debolmente tipizzata.

    
risposta data 09.08.2012 - 10:37
fonte
2

In Squeak Smalltalk / su interi crea oggetti Fraction. Quindi, anche se questo non è lo stesso della divisione float, ancora (1/6)*6 restituisce 1.

    
risposta data 09.08.2012 - 16:35
fonte
2

Sì, ho appena controllato il TI-99 / 4A integrato TI BASIC . Poiché tratta tutte le espressioni numeriche come in virgola mobile, anche l'operazione di divisione è a virgola mobile.

 TI BASIC READY
>PRINT 1/6
  .1666666667

>
    
risposta data 09.08.2012 - 16:48
fonte
2

VB ( VB.Net , VB6 , VBA ...)

L'operatore di divisione in interi è \

    
risposta data 09.08.2012 - 20:29
fonte
2

MATLAB. I valori letterali numerici sono i doppi per impostazione predefinita.

>> 1/6
ans =
    0.1667
    
risposta data 09.08.2012 - 20:34
fonte
2

Clojure usa le frazioni per impostazione predefinita. Non è lo stesso di 1.0 / 6.0, ma puoi convertirlo con float o double quando ti serve.

user=> (/ 1 6)
1/6
user=> (* (/ 1 6) 2)
1/3
user=> (pos? (/ 1 6)) ; Is 1/6 > 0?
true
user=> (float (/ 1 6))
0.16666667
    
risposta data 09.08.2012 - 20:38
fonte
1

Sorprendentemente, sembra funzionare correttamente in Windows PowerShell (versione 3) .

PS C:\> 1.0 / 6.0
0.166666666666667

PS C:\> 1/6
0.166666666666667

Sembra funzionare anche in Python 3 come menzionato in Sepp2k. Le altre due lingue che ho prontamente disponibili su REPL, Scala e Ruby, fanno entrambe la divisione intera e danno 0.

    
risposta data 09.08.2012 - 16:35
fonte
0

Il linguaggio Rexx produce sempre una risposta aritmetica corretta. Ad esempio: 5/2 = 2,5. Rexx è un ottimo linguaggio che non è stato abbastanza utilizzato. In teoria, quando un compilatore non può determinare cosa vuoi, è meglio fare la matematica corretta, tuttavia, questo potrebbe non essere efficiente. Rexx fornisce anche l'operatore //.

    
risposta data 09.08.2012 - 23:18
fonte

Leggi altre domande sui tag