Overløb af hele tal

Håndtering af overløb af hele tal i forskellige programmeringssprog
Sprog Unsigneret heltal Signeret heltal
Ada modulo typens modulus udløser Constraint_Error
C/C++ modulo potens af to udefineret adfærd
C# modulo potens af 2 i ukontrolleret sammenhæng; System.OverflowException hæves i kontrolleret kontekst
Java N/A modulo potens af to
JavaScript alle tal er dobbelt-
JavaScript alle tal er dobbelt-præcision flydende-komma undtagen det nye BigInt
MATLAB Builtin integers saturate. Fast-point-integriteter kan konfigureres til wrap eller saturate
Python 2 N/A konverteres til lang type (bigint)
Seed7 N/A raise OVERFLOW_ERROR
Scheme N/A konverter til bigNum
Simulink konfigurerbart til wrap eller saturation
Smalltalk N/A konverterer til LargeInteger
Swift Kommer med fejl, medmindre der anvendes særlige overløbsoperatører.

DetectionEdit

Den implementering UBSan af overløbsdetektion ved kørsel er tilgængelig for C-compilere.

I Java 8 er der overloadede metoder, f.eks. som Math.addExact(int, int), som kaster ArithmeticException i tilfælde af overløb.

Computer Emergency Response Team (CERT) har udviklet As-if Infinitely Ranged (AIR) integer-modellen, en stort set automatiseret mekanisme til at eliminere heltalsoverløb og trunkering i C/C++ ved hjælp af fejlhåndtering ved kørselstid.

AvoidanceEdit

Gennem at allokere variabler med datatyper, der er store nok til at indeholde alle værdier, der muligvis kan beregnes og lagres i dem, er det altid muligt at undgå overløb. Selv når den tilgængelige plads eller de faste datatyper, der leveres af et programmeringssprog eller -miljø, er for begrænsede til, at det er muligt at allokere variabler defensivt med generøse størrelser, er det ofte muligt ved omhyggeligt at ordne operationer og kontrollere operander på forhånd at sikre på forhånd, at resultatet aldrig bliver større end det, der kan lagres. Statiske analyseværktøjer, formel verifikation og design by contract-teknikker kan bruges til med større sikkerhed og robusthed at sikre, at et overløb ikke ved et uheld kan opstå.

HandlingEdit

Hvis det forventes, at der kan opstå et overløb, kan der indsættes test i programmet for at opdage, når det sker eller er ved at ske, og foretage anden behandling for at afbøde det. Hvis f.eks. et vigtigt resultat, der er beregnet ud fra brugerens input, løber over, kan programmet stoppe, afvise input og måske bede brugeren om et andet input, i stedet for at programmet fortsætter med det ugyldige input, der løber over, og som følge heraf sandsynligvis ikke fungerer korrekt. Hele denne proces kan automatiseres: det er muligt automatisk at syntetisere en behandler for et heltalsoverløb, hvor behandleren f.eks. er et rent exit.

CPU’er har generelt en måde at opdage dette på for at understøtte addition af tal, der er større end deres registerstørrelse, typisk ved hjælp af en statusbit; teknikken kaldes multiple-precision aritmetik.Det er således muligt at addere to tal, der hver er to bytes brede, ved hjælp af blot en byteaddition i trin: først adderes de lave bytes og derefter de høje bytes, men hvis det er nødvendigt at udføre ud af de lave bytes, er der tale om aritmetisk overløb af byteadditionen, og det bliver nødvendigt at detektere og inkremere summen af de høje bytes.

Håndtering af et muligt overløb i en beregning kan nogle gange give et valg mellem at udføre en kontrol før selve beregningen (for at afgøre, om der vil ske et overløb) eller efter den (for at overveje, om det sandsynligvis er sket på baggrund af den resulterende værdi). Der bør udvises forsigtighed med hensyn til sidstnævnte valg. For det første, da det måske ikke er en pålidelig detektionsmetode (f.eks. vil en addition ikke nødvendigvis føre til en lavere værdi). For det andet, fordi selve forekomsten af overløb i nogle tilfælde kan være en udefineret adfærd. I programmeringssproget C resulterer overløb af ikke-fortegnede heltalstyper i wrapping, men overløb af signerede heltalstyper er udefineret adfærd; en C-compiler kan derfor gå ud fra, at programmøren har sikret sig, at signeret overløb umuligt kan forekomme, og den kan derfor stille og roligt optimere enhver kontrol efter beregningen, som omfatter kontrol af resultatet for at opdage det, uden at give programmøren nogen advarsel om, at dette er sket. Det er således tilrådeligt altid at foretrække at implementere kontroller før beregninger og ikke efter dem.

Eksplicit propagationRediger

hvis en værdi er for stor til at blive gemt, kan den tildeles en særlig værdi, der angiver, at der er sket overløb, og derefter få alle efterfølgende operationer til at returnere denne flagværdi. Sådanne værdier kaldes nogle gange NaN, for “not a number” (ikke et tal). Dette er nyttigt, således at problemet kan kontrolleres én gang i slutningen af en lang beregning i stedet for efter hvert trin. Dette understøttes ofte i flydepunktshardware kaldet FPU’er.

ProgrammeringssprogunderstøttelseRediger

Programmeringssprog implementerer forskellige afbødningsmetoder mod et utilsigtet overløb: Ada, Seed7 (og visse varianter af funktionelle sprog), udløser en undtagelsesbetingelse ved overløb, mens Python (siden 2.4) konverterer den interne repræsentation af tallet problemfrit for at matche dets vækst og til sidst repræsenterer det som long – hvis evne kun er begrænset af den tilgængelige hukommelse.

I sprog med indfødt understøttelse af aritmetik med vilkårlig præcision og type-sikkerhed (såsom Python, Smalltalk eller Common Lisp), bliver tal automatisk forfremmet til en større størrelse, når der opstår overløb, eller der bliver kastet undtagelser (signaleret betingelser), når der er en intervalbegrænsning. Det kan derfor være nyttigt at anvende sådanne sprog for at afhjælpe dette problem. I nogle af disse sprog er der dog stadig situationer, hvor der kan opstå et heltalsoverløb. Et eksempel er eksplicit optimering af en kodevej, som profilereren anser for at være en flaskehals. I tilfældet Common Lisp er dette muligt ved at bruge en eksplicit deklaration til at type-annotere en variabel til et ord i maskinstørrelse (fixnum) og sænke type-sikkerhedsniveauet til nul for en bestemt kodeblok.

I skarp kontrast til ældre sprog som C har nogle nyere sprog, som f.eks. Rust, indbygget funktionalitet, der gør det muligt let at opdage og for brugeren at vælge, hvordan overløb skal håndteres fra sag til sag. I Rust mangler brugen af grundlæggende matematiske operatorer naturligvis en sådan fleksibilitet, men i Rust kan brugerne alternativt udføre beregninger via et sæt metoder, der leveres af hver af de primitive heltalstyper. Disse metoder giver brugerne flere valgmuligheder mellem at udføre en “kontrolleret” (eller “overløbende”) operation (som via returneringstypen angiver, om der er sket overløb eller ej); en “ukontrolleret” operation; en operation, der udfører wrapping, eller en operation, der udfører mætning ved de numeriske grænser.

Mættet aritmetikRediger

I computergrafik eller signalbehandling er det typisk at arbejde med data, der spænder fra 0 til 1 eller fra -1 til 1. Tag f.eks. et gråskala-billede, hvor 0 repræsenterer sort, 1 repræsenterer hvid, og værdierne derimellem repræsenterer gråtoner. En operation, som man måske ønsker at understøtte, er at lysne billedet ved at multiplicere hver pixel med en konstant. Med mættet aritmetik kan man bare blindt gange hver pixel med denne konstant uden at bekymre sig om overløb ved blot at holde sig til et rimeligt resultat, at alle disse pixels større end 1 (dvs. “lysere end hvid”) bare bliver hvide, og alle værdier “mørkere end sort” bare bliver sorte.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.