Perché lo zero negativo è importante?

59

Sono confuso sul motivo per cui ci interessano le diverse rappresentazioni per lo zero positivo e negativo.

Mi ricordo vagamente di aver letto che affermare che avere una rappresentazione zero negativa è estremamente importante nella programmazione che coinvolge numeri complessi. Non ho mai avuto l'opportunità di scrivere codice che coinvolge numeri complessi, quindi sono un po 'sconcertato sul perché questo sia il caso.

L'articolo di Wikipedia sul concetto non è particolarmente utile; fa solo vaghe affermazioni sullo zero firmato rendendo più semplici le operazioni matematiche in virgola mobile, se ho capito bene. Questa risposta elenca un paio di funzioni che si comportano in modo diverso, e forse qualcosa potrebbe essere dedotto dagli esempi se hai familiarità con come potrebbero essere usati (Sebbene, l'esempio particolare delle radici quadrate complesse appaia sbagliato , poiché i due numeri sono matematicamente equivalenti, a meno che non abbia un equivoco.) Ma non sono stato in grado di trovare una chiara affermazione del tipo di guai in cui potresti entrare se non ci fosse. Le risorse più matematiche che sono stato in grado di trovare affermano che non c'è alcuna distinzione tra i due da una prospettiva matematica, e l'articolo di Wikipedia sembra suggerire che questo è raramente visto al di fuori dell'informatica oltre a descrivere i limiti.

Allora, perché uno zero negativo è prezioso nel calcolo? Sono sicuro che mi manca qualcosa.

    
posta jpmc26 01.05.2015 - 04:10
fonte

5 risposte

64

È necessario tenere presente che nell'aritmetica FPU, 0 non deve necessariamente significare esattamente zero, ma anche un valore troppo piccolo per essere rappresentato utilizzando un dato tipo di dati, ad es.

a = -1 / 1000000000000000000.0

a è troppo piccolo per essere rappresentato correttamente da float (32 bit), quindi è "arrotondato" a -0.

Ora, diciamo che il nostro calcolo continua:

b = 1 / a

Poiché a è float, il risultato sarà -infinity che è abbastanza lontano dalla risposta corretta di -1000000000000000000.0

Ora calcoliamo b se non c'è -0 (quindi a viene arrotondato a +0):

b = 1 / +0
b = +infinity

Il risultato è di nuovo sbagliato a causa dell'arrotondamento, ma ora è "più sbagliato" - non solo numericamente, ma soprattutto a causa di un segno diverso (il risultato è un + infinito, il risultato corretto è -1000000000000000000.0).

Potresti ancora dire che non ha molta importanza in quanto entrambi sono sbagliati. La cosa importante è che ci sono molte applicazioni numeriche in cui il risultato più importante del calcolo è il segno - ad es. quando decidi se girare a sinistra oa destra all'incrocio usando un algoritmo di apprendimento automatico, puoi interpretare il valore positivo = > gira a sinistra, valore negativo = > gira a destra, la "grandezza" effettiva del valore è solo "coefficiente di confidenza".

    
risposta data 01.05.2015 - 17:30
fonte
8

In primo luogo, come crei un -0? Ci sono due modi: (1) eseguire un'operazione a virgola mobile in cui il risultato matematico è negativo, ma così vicino a zero che viene arrotondato a zero e non a un numero diverso da zero. Quel calcolo darà un -0. (b) Alcune operazioni che coinvolgono gli zeri: Moltiplicare uno zero positivo per un numero negativo, o dividere uno zero positivo per un numero negativo o negare uno zero positivo.

Avere uno zero negativo semplifica la moltiplicazione e la divisione un po ', il segno di x * yo x / y è sempre il segno di x, esclusivo o il segno di y. Senza zero negativo, ci dovrebbe essere qualche controllo in più per sostituire -0 con +0.

Ci sono alcune situazioni molto rare in cui è utile. Puoi verificare se il risultato di una moltiplicazione o divisione è matematicamente maggiore o minore di zero, anche se esiste un underflow (purché tu sappia che il risultato non è uno zero matematico). Non ricordo di aver mai scritto codice in cui fa la differenza.

Ottimizzazione dei compilatori odio -0. Ad esempio, non puoi sostituire x + 0.0 con x, perché il risultato non dovrebbe essere x se x è -0.0. Non puoi sostituire x * 0.0 con 0.0, perché il risultato dovrebbe essere -0.0 se x < 0 o x è -0.0.

    
risposta data 02.05.2015 - 18:41
fonte
6

C # Double conforme a IEEE 754

    double a = 3.0;
    double b = 0.0;
    double c = -0.0;

    Console.WriteLine(a / b);
    Console.WriteLine(a / c);

stampe:

Infinity
-Infinity

in realtà per spiegare un po '...

Double d = -0.0; 

Questo significa qualcosa di molto più vicino a d = The Limit of x as x approaches 0- o The Limit of x as x approaches 0 from the negatives .

Per rispondere al commento di Philipp ...

Zero fondamentalmente negativo significa underflow.

C'è pochissimo uso pratico per zero negativo se c'è ...

per esempio, questo codice (ancora C #):

double a = -0.0;
double b = 0.0;

Console.WriteLine(a.Equals(b));
Console.WriteLine(a==b);
Console.WriteLine(Math.Sign(a));

produce questo risultato:

True
True
0

Per spiegare in modo informale, tutti i valori speciali che un punto mobile IEEE 754 può avere (infinito positivo, infinito negativo, NAN, -0,0) non hanno alcun significato nel senso pratico. Non possono rappresentare alcun valore fisico o alcun valore che abbia senso nel calcolo del "mondo reale". Ciò che intendono è fondamentalmente questo:

  • infinito positivo significa un overflow alla fine positiva che un punto variabile può rappresentare
  • infinito negativo indica un overflow all'estremità positiva che un punto mobile può rappresentare
  • zero negativo indica un underflow e gli operandi hanno segni opposti
  • zero positivo può significa un underflow e gli operandi hanno lo stesso segno
  • NAN significa che il tuo calcolo è indefinitamente compiacente, come sqrt(-7) , o non ha un limite come 0/0 o come PositiveInfinity/PositiveInfinity
risposta data 01.05.2015 - 16:57
fonte
5

La domanda su come questo si riferisce a calcoli con numeri complessi è davvero al centro del motivo per cui sia +0 che -0 esistono in virgola mobile. Se si studia l'Analisi Complessa, si scopre rapidamente che le funzioni continue dal Complesso al Complesso di solito non possono essere considerate "a valore singolo" a meno che non si adotti la "finzione educata" che le uscite formino ciò che è noto come "superficie di Riemann". Ad esempio, il logaritmo complesso assegna ad ogni input infinitamente molte uscite; quando li si "connette" per formare un output continuo, si finisce con tutte le parti reali che formano una superficie a "cavatappi infinita" attorno all'origine. Una curva continua che attraversa l'asse reale "verso il basso dal lato immaginario positivo" e un'altra curva che "avvolge il polo" e attraversa l'asse reale "verso l'alto dal lato negativo-immaginario" assumerà diversi valori sull'asse reale perché passano su diversi "fogli" della superficie di Riemann.

Ora applicalo a un programma numerico che calcola usando il floating-point complesso. L'azione intrapresa dopo un dato calcolo può essere molto diversa a seconda di quale 'foglio' il programma è attualmente 'acceso', e il segno dell'ultimo risultato calcolato probabilmente ti dice quale 'foglio'. Supponiamo ora che il risultato sia zero? Ricorda, qui 'zero' significa davvero 'troppo piccolo per rappresentare correttamente'. Ma se il calcolo può essere organizzato in modo da preservare il segno - (ricorda quale "foglio") quando il risultato è zero, allora il codice può controllare il segno ed eseguire l'azione giusta anche in questa situazione.

    
risposta data 26.02.2016 - 16:04
fonte
1

Il motivo è più semplice del solito

Ovviamente ci sono molti hack che sembrano davvero belli e sono utili (come l'arrotondamento a -0.0 o +0.0 ma assumiamo che abbiamo una rappresentazione di int firmato con un segno meno / segno più all'inizio (so che è risolto dal codice binario U2 in numeri interi ma assume una rappresentazione meno complessa di doppio):

0 111 = 7
^ sign

Che cosa succede se c'è un numero negativo?

1 111 = -7

Ok, è semplice. Quindi rappresentiamo 0:

0 000 = 0

Anche quello va bene. Ma per quanto riguarda 1 000 ? Dev'essere un numero proibito? Meglio di no.

Quindi supponiamo che ci siano due tipi di zero:

0 000 = +0
1 000 = -0

Bene, questo semplificherebbe i nostri calcoli e darebbe per forza alcune caratteristiche aggiuntive. Quindi +0 e -0 provengono da soli problemi di rappresentazione binaria.

    
risposta data 01.05.2015 - 18:07
fonte

Leggi altre domande sui tag