Överskridande av heltal

Hantering av överskridande av heltal i olika programmeringsspråk
Språk Integertal utan tecken Integertal med tecken
Ada modulo typens modulus raise Constraint_Error
C/C++ modulo potens av två undefinierat beteende
C# modulo potens av 2 i okontrollerat sammanhang; System.OverflowException tas upp i kontrollerad kontext
Java N/A modulo potens av två
JavaScript alla tal är dubbla-precision floating-point utom det nya BigInt
MATLAB Builtin integers saturate. Fast-point integers konfigurerbart för att omsluta eller mätta
Python 2 N/A konvertera till lång typ. (bigint)
Seed7 N/A raise OVERFLOW_ERROR
Scheme N/A konvertera till bigNum
Simulink konfigurerbart till wrap eller saturate
Smalltalk N/A konverterar till LargeInteger
Swift Gör fel om man inte använder speciella överflödsoperatörer.

DetectionEdit

Den implementering UBSan av överflödsdetektering vid körning finns tillgänglig för C-kompilatorer.

I Java 8 finns det överbelastade metoder, till exempel som Math.addExact(int, int), som kastar ArithmeticException i händelse av överflöd.

Computer Emergency Response Team (CERT) har utvecklat helhetsmodellen As-if Infinitely Ranged (AIR), en till stor del automatiserad mekanism för att eliminera helhetsöverflöde och trunkering i C/C++ med hjälp av felhantering vid körning.

AvoidanceEdit

Då variabler tilldelas variabler med datatyper som är tillräckligt stora för att innehålla alla värden som möjligen kan beräknas och lagras i dem, är det alltid möjligt att undvika överflöde. Även när det tillgängliga utrymmet eller de fasta datatyper som tillhandahålls av ett programmeringsspråk eller en miljö är för begränsade för att tillåta att variabler defensivt allokeras med generösa storlekar, är det genom att noggrant ordna operationer och kontrollera operander i förväg ofta möjligt att på förhand säkerställa att resultatet aldrig blir större än vad som kan lagras. Verktyg för statisk analys, formell verifiering och design by contract-tekniker kan användas för att på ett säkrare och robustare sätt säkerställa att ett överflöde inte kan uppstå av misstag.

HandlingEdit

Om man räknar med att ett överflöde kan inträffa kan tester införas i programmet för att upptäcka när det inträffar, eller är på väg att inträffa, och göra annan behandling för att mildra det. Om t.ex. ett viktigt resultat som beräknats från användarens inmatning går över, kan programmet stanna, avvisa inmatningen och kanske uppmana användaren att göra en annan inmatning, i stället för att programmet fortsätter med den ogiltiga inmatningen som gått över och troligen fungerar dåligt som en följd av detta. Hela denna process kan automatiseras: det är möjligt att automatiskt syntetisera en handläggare för ett heltalsöverskridande, där handläggaren till exempel är en ren exit.

CPU:er har i allmänhet ett sätt att upptäcka detta för att stödja addition av tal som är större än deras registerstorlek, vanligtvis med hjälp av en statusbit; tekniken kallas multipelprecisionsaritmetik.Det är alltså möjligt att addera två tal som är två byte breda vardera med hjälp av bara en byteaddition i steg: addera först de låga bytena och sedan de höga bytena, men om det är nödvändigt att föra ut de låga bytena är detta ett aritmetiskt överskridande av byteadditionen och det blir nödvändigt att upptäcka och öka summan av de höga bytena.

Hantering av eventuellt överskridande av en beräkning kan ibland innebära ett val mellan att utföra en kontroll före själva beräkningen (för att avgöra om ett överskridande kommer att inträffa eller inte), eller efter den (för att överväga om det sannolikt inträffade baserat på det resulterande värdet eller inte). Man bör vara försiktig med det senare valet. För det första eftersom det kanske inte är en tillförlitlig upptäcktsmetod (till exempel behöver en addition inte nödvändigtvis leda till ett lägre värde). För det andra, eftersom förekomsten av själva överflödet i sig i vissa fall kan vara ett odefinierat beteende. I programmeringsspråket C resulterar överskridande av icke-förtecknade heltalstyper i omslag, men överskridande av tecknade heltalstyper är ett odefinierat beteende. Följaktligen kan en C-kompilator anta att programmeraren har försäkrat sig om att tecknat överskridande inte kan förekomma, och därför kan den i tysthet optimera alla kontroller efter beräkningen som innebär att man kontrollerar resultatet för att upptäcka det, utan att ge programmeraren någon varning om att detta har gjorts. Det är därför lämpligt att alltid föredra att implementera kontroller före beräkningar och inte efter dem.

Explicit propagationRedigera

Om ett värde är för stort för att lagras kan det tilldelas ett särskilt värde som indikerar att ett överflöde har inträffat och sedan få alla efterföljande operationer att returnera detta flaggvärde. Sådana värden kallas ibland för NaN, för ”not a number”. Detta är användbart så att problemet kan kontrolleras en gång i slutet av en lång beräkning i stället för efter varje steg. Detta stöds ofta i maskinvara för flyttal som kallas FPU:er.

Stöd för programspråkRedigera

Programspråk implementerar olika begränsningsmetoder mot ett oavsiktligt överflöde: Ada, Seed7 (och vissa varianter av funktionella språk) utlöser ett undantagstillstånd vid överskridande, medan Python (sedan 2.4) sömlöst omvandlar den interna representationen av talet för att matcha dess tillväxt, och så småningom representerar det som long – vars förmåga endast begränsas av det tillgängliga minnet.

I språk med stöd för aritmetik med godtycklig precision och typsäkerhet (t.ex. Python, Smalltalk eller Common Lisp), flyttas talen automatiskt till en större storlek vid överflöden, eller så utlöses undantag (villkor signaleras) när det finns en begränsning för intervallet. Det kan därför vara bra att använda sådana språk för att minska detta problem. I vissa sådana språk finns det dock fortfarande situationer där ett heltalsöverskridande kan inträffa. Ett exempel är explicit optimering av en kodväg som av profileraren anses vara en flaskhals. I fallet Common Lisp är detta möjligt genom att använda en explicit deklaration för att typ-annotera en variabel till ett ord i maskinstorlek (fixnum) och sänka typ-säkerhetsnivån till noll för ett visst kodblock.

I skarp kontrast till äldre språk som C erbjuder vissa nyare språk, till exempel Rust, inbyggd funktionalitet som gör det möjligt att enkelt upptäcka och att användaren själv kan välja hur ett överflöde ska hanteras från fall till fall. I Rust saknar användningen av grundläggande matematiska operatörer naturligtvis sådan flexibilitet, men användarna kan alternativt utföra beräkningar via en uppsättning metoder som tillhandahålls av var och en av de primitiva heltalstyperna. Dessa metoder ger användaren flera valmöjligheter mellan att utföra en ”kontrollerad” (eller ”överflödig”) operation (som anger om överflöd har inträffat eller inte via returtypen); en ”okontrollerad” operation; en operation som utför omslag eller en operation som utför mättnad vid de numeriska gränserna.

Mättad aritmetikRedigera

I datorgrafik eller signalbehandling är det typiskt att arbeta med data som sträcker sig från 0 till 1 eller från -1 till 1. Ta till exempel en gråskalebild där 0 representerar svart, 1 representerar vitt och värdena däremellan representerar gråtoner. En operation som man kanske vill stödja är att ljusa upp bilden genom att multiplicera varje pixel med en konstant. Mättad aritmetik gör det möjligt att bara blint multiplicera varje pixel med den konstanten utan att oroa sig för överflöde genom att bara hålla sig till ett rimligt resultat som innebär att alla dessa pixlar som är större än 1 (dvs. ”ljusare än vitt”) bara blir vita och alla värden som är ”mörkare än svart” bara blir svarta.

Lämna ett svar

Din e-postadress kommer inte publiceras.