Negative Zero

Originally published by Howdy Pierce on November 17th 2017 6,483 reads

Howdy Pierce Hacker Noon profilbild

@howdypiercehowdy Pierce

ordförande och grundare

Facebook social iconTwitter social icon

min fru tar upp följande berättelse när som helst hon vill göra poängen att jag är pedantisk: när en av mina döttrar gick i andra klass berättade hennes matematiklärare klassen att ett tal dividerat med noll var ett. Jag streckade bort ett passionerat e-postmeddelande till läraren och insisterade på att resultatet måste vara odefinierat. Förmodligen är detta bevis på att jag ibland är svår att vara med.

visar sig skämtet kan vara på mig – även om det fortfarande är svårt att stödja andra klassens lärares svar. Jag lärde mig nyligen en massa saker som jag inte visste om flytpunkt matematik:

  • Det finns ett värde för negativ noll, separat från vanlig (positiv?) noll. Dessa två nollor definieras vara lika med varandra och ändå är de distinkta värden.
  • x 0,0, för x 0.0, är inte ett fel. Istället är resultatet antingen positiv oändlighet eller negativ oändlighet, enligt den vanliga teckenkonventionen.
  • fallet med 0,0 0,0 0,0 är ett fel (specifikt är det ”inte ett nummer” eller nan).
  • -0.0 + -0.0 = -0.0, -0.0 + 0.0 = 0.0, och -0,0 0,0 0,0 = -0,0

dessa regler härrör från IEEE 754 ”Standard för flytpunkts aritmetik”, som standardiserade flytpunktsrepresentationer över plattformar. Den senaste versionen av standarden slutfördes 2008 men den ursprungliga versionen utfärdades 1985, så detta beteende är inte nytt. Reglerna ovan är sanna i både C (gcc) och Swift på min Mac, och även sant i Swift på en iPhone. Python på Mac stöder negativ noll för floats, men kastar ett undantag när du försöker dela med noll av något tecken.

det finns ett par överraskande följder för dessa regler:

  • eftersom 0,0 och -0,0 måste jämföras Som lika, testet (x < 0.0) returnerar inte sant för varje negativt tal – det misslyckas för negativ noll. För att bestämma tecknet på ett nollvärde måste du därför använda plattformens inbyggda teckenfunktion, till exempel Dubbel.logga in Swift. Eller jag antar att du kan bitmanipulera den råa representationen av dubbel, vilket är väldigt mycket en C-programmerares svar.
  • Om a = b-c, följer det inte nödvändigtvis att b = a-c, eftersom detta också misslyckas för det fall där c är noll av något tecken.

Jag är inte en talteoretiker, men jag tycker att begreppen ovan är överraskande.

ett omedelbart problem: Oändlighet är inte ett tal, som noll eller 3,25 eller kub. Snarare är oändligheten ett koncept. Det är sant att de rationella talen är räknbart oändliga — men oändligheten är inte medlem i uppsättningen rationella tal.

dessutom, ur ett talteoriperspektiv, är uppdelning med noll meningslös. Du kan förstå varför om du får exakt om vad division betyder. Tekniskt sett är ”division” ”multiplikation med ett tals inversa”, där det inversa uppfyller: en ASIC a^-1 = 1. Noll är det enda numret i uppsättningen reella tal som helt enkelt inte har någon multiplikativ invers. Och eftersom denna inversa inte existerar, kan vi inte gå runt multiplicera med det.

men säkert visste de människor som designade flytande punktnummer allt detta. Så jag undrade varför det beskrivna beteendet kom att skrivas in i IEEE-standarden.

för att börja, låt oss överväga det problem som flytande matematik försöker ta itu med. De reella talen är uncountably oändliga, och ändå vill vi representera hela denna uppsättning inom gränserna för ändligt datorminne. Med en 64-bitars dubbel finns det 2^64 möjliga symboler, och designarna av IEEE-standarden försökte kartlägga dessa symboler på uppsättningen reella tal på ett sätt som var både användbart för verkliga applikationer och också ekonomiskt genomförbart med tanke på begränsningarna i början av 80-talet kisel. Med tanke på de grundläggande kraven skulle tydligt approximationer användas.

resonemanget för negativ noll verkar hittills till ett papper från 1987 av William Kahan, en Berkeley-professor som anses vara ”far till flytande punkt” och som senare vann Turing Award för sitt arbete med att utarbeta IEEE 754. Det visar sig att förekomsten av negativ noll är nära knuten till förmågan att dela med noll.

låt oss börja med att diskutera den vanliga orsaken till att uppdelning med noll inte är tillåten. En na ubicve-inställning till uppdelning med noll är observationen att:

med andra ord, när x blir mindre blir resultatet av 1/x större. Men det här är bara sant när x närmar sig 0 från den positiva sidan (det är därför det finns det lilla plustecknet ovan). Kör samma tankeexperiment från den negativa sidan:

som ett resultat är den generiska gränsen för 1/x som x närmar sig 0 odefinierad, eftersom det finns en diskontinuitet (vad Kahan kallar en slits) i funktionen 1/x.

men genom att införa en undertecknad noll kunde Kahan och IEEE-utskottet komma runt svårigheten. Intuitivt tas tecknet på en noll för att indikera den riktning gränsen närmar sig från. Som Kahan säger i sitt papper från 1987:

snarare än att tänka på +0 och -0 som distinkta numeriska värden, tänk på deras teckenbit som en hjälpvariabel som förmedlar en bit information (eller felinformation) om någon numerisk variabel som tar 0 som sitt värde. Vanligtvis är denna information irrelevant; värdet på 3+x är inte annorlunda för x := +0 än för x := -0…. Några extraordinära aritmetiska operationer påverkas emellertid av zero: s tecken; till exempel 1/ (+0) = + bisexuell, men 1/ (-0) = –ASIC.

Jag har gjort min fred med konceptet genom att anta en rationalisering som föreslagits av min partner Mike Perkins: de 2^64 tillgängliga symbolerna är tydligt otillräckliga för att representera hela uppsättningen reella tal. Så, IEEE-designarna avsatte några av dessa symboler för speciella betydelser. I den meningen betyder inte riktigt ”oändlighet” — istället betyder det ”ett reellt tal som är större än vad vi annars kan representera i vår flytpunktssymbol.”Och därför betyder +0 inte riktigt” noll ”utan snarare” ett reellt tal som är större än sant 0 men mindre än något positivt tal vi kan representera.”

Förresten, när jag undersökte denna fråga upptäckte jag att även Kahan inte älskar tanken på negativ noll:

signerad noll — ja, den signerade Noll var en smärta i röven som vi kunde eliminera om vi använde projektivt läge. Om det bara fanns en oändlighet och en noll kunde du göra det bra; då brydde du dig inte om tecknet på noll och du brydde dig inte om oändlighetens tecken. Men om du å andra sidan insisterade på vad jag skulle ha betraktat som det mindre valet av två oändligheter, så kommer du att sluta med två signerade nollor. Det var verkligen inte en väg runt det och du fastnade med det.”(Från en intervju med Kahan genomfördes 2005.)

Jag är inte säker på om att skriva ett blogginlägg tio år senare kompenserar för räcke mot en dålig lärare i andra klass. För hennes del rullade min dotter, nu i gymnasiet, bara ögonen när jag började prata om division med noll vid middagen. Så kanske den” svåra att vara runt ” är ärftlig.

Kahan, W., ”Grenskärningar för komplexa elementära funktioner, eller mycket Ado om ingenting Teckenbit”, den senaste tekniken i numerisk analys, (Red. Iserles och Powell), Clarendon Press, Oxford, 1987, tillgänglig här.

Tags

Join Hacker Noon

Create your free konto för att låsa upp din anpassade läsupplevelse.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *