2016-03-16 12 views
5

In PHP, permette di creare una variabile e impostarla valore ai 0:Perché il float di PHP 0 (zero) viene visualizzato con il segno?

$x = 0; 
echo $x; 

sarebbe visualizzare 0. Se ci si moltiplicare per -1:

$x = -1 * $x; 
echo $x; 

ancora vediamo 0. Ma se $x è un float:

$x = 0; 
$x = (float)$x; 
$x = -1 * $x; 
echo $x; 

otterremmo l'output: -0.

Perché è quello? Non dovrebbe essere sempre visualizzato senza segno, indipendentemente dal suo tipo sottostante?

+4

Ancora più divertente, prova '$ x = $ x + 0' e stampa di nuovo. La vera ragione è che PHP (e i computer, in generale, davvero) potrebbero o meno rappresentare effettivamente un particolare float con quel valore esatto. Compreso lo zero. È del tutto possibile che '-0' sia in realtà' -0,00000000000003' – CollinD

+2

La cosa principale da ottenere è che non si dovrebbe mai usare '==' con numeri mobili. – Gasim

+1

dupe? http://stackoverflow.com/questions/588004/is-floating-point-math-broken –

risposta

1

Poiché PHP tipicamente utilizza la IEEE 754 formato doppio precisione per i numeri in virgola che consiste di galleggiamento:

1) segno (1 bit)

2) esponente (11 bit)

3) frazione (52 bit)

Se si moltiplica $ x con -1 viene impostato il bit di segno.

I numeri interi utilizzano i due complementi in cui il bit più significativo (MSB) determina il segno. Il MSB è 0 se si moltiplica con 0.

See: https://en.wikipedia.org/wiki/Signed_zero

+0

Non penso che questo risponda alla parte "Perché" della domanda. Il moltiplicare per -1 cambiando il comportamento del segno non si applica ai NaN e potrebbe essere stato definito per non applicarsi a zero. –

+0

@PatriciaShanahan: Sono d'accordo che la mia risposta manchi di casi d'uso per zeri firmati, ma copre l'aspetto tecnico e l'implementazione di PHP. – Rocki

1

virgola mobile a zero viene usato per più di zero solo assoluto. È usato per rappresentare risultati minuscoli, grandezza assoluta troppo piccola anche per numeri subnormali.

In alcuni calcoli, il segno di tali numeri è importante. Ad esempio, è importante che 1/+ 0 sia l'infinito positivo, ma 1/-0 è l'infinito negativo. Per farlo funzionare correttamente, moltiplicando 0 per -1 si ottiene -0.

Ad esempio, vedere il documento di W. Kahan "Branch Cuts for Complex Elementary Functions or Much Ado About Nothing's Sign Bit".

+0

Sì, ma in PHP nella maggior parte dei casi non si controlla quando improvvisamente int diventa float. E quindi il problema con una visualizzazione non intenzionale. – Gacek

+0

@Gacek Le regole di PHP per la conversione dei tipi sono complicate e talvolta sciocche, ma sono del tutto deterministiche. Si * fa * "controlla" quando un int diventa un float. – Sneftel