Egész számok túlcsordulása

.

Integer overflow handling in various programming languages
Language Unsigned integer Signed integer
Ada modulo a típus modulusa raise Constraint_Error
C/C++ modulo power of two undefined behavior
C# modulo power of 2 in unchecked context; System.OverflowException ellenőrzött kontextusban
Java N/A modulo kettes hatványa
JavaScript minden szám duplája-pontosságú lebegőpontos, kivéve az új BigInt
MATLAB Builtin egész számok telítettek. Fix-pont egész számok konfigurálhatóak, hogy felgöngyölítsék vagy telítsék
Python 2 N/A konvertálják hosszú típusba. (bigint)
Seed7 N/A raise OVERFLOW_ERROR
Scheme N/A konvertálja bigNummá
Simulink konfigurálható, hogy tekerje vagy telítse
Smalltalk N/A konvertálja LargeIntegerré
Swift Hibát okoz, hacsak nem használ speciális túlcsordulási operátorokat.

DetectionEdit

A futásidejű túlcsordulás-érzékelés UBSan implementációja elérhető a C fordítóprogramokhoz.

A Java 8-ban vannak túlterhelt metódusok, például mint a Math.addExact(int, int), amelyek túlcsordulás esetén ArithmeticException dobnak.

A CERT (Computer Emergency Response Team) kifejlesztette az AIR (As-if Infinitely Ranged) integer modellt, egy nagyrészt automatizált mechanizmust az egész számok túlcsordulásának és csonkolásának kiküszöbölésére C/C++-ban futásidejű hibakezeléssel.

ElkerüléseEdit

A túlcsordulás mindig elkerülhető, ha olyan adattípusú változókat rendelünk ki, amelyek elég nagyok ahhoz, hogy minden olyan értéket tartalmazzanak, amely esetleg kiszámítható és tárolható bennük. Még akkor is, ha a rendelkezésre álló hely vagy a programozási nyelv vagy környezet által biztosított rögzített adattípusok túlságosan korlátozottak ahhoz, hogy lehetővé tegyék a változók nagyvonalú méretű védekező kiosztását, a műveletek gondos sorrendbe állításával és az operandusok előzetes ellenőrzésével gyakran a priori biztosítható, hogy az eredmény soha nem lesz nagyobb, mint amekkora tárolható. Statikus elemzési eszközökkel, formális verifikációval és szerződéses tervezési technikákkal magabiztosabban és robusztusabban biztosítható, hogy véletlenül sem következhet be túlcsordulás.

HandlingEdit

Ha előre látható, hogy túlcsordulás következhet be, akkor a programba beilleszthetünk olyan teszteket, amelyek érzékelik, ha ez megtörténik vagy meg fog történni, és más feldolgozást végeznek annak enyhítésére. Például, ha egy fontos, a felhasználói bemenetből számított eredmény túlcsordul, a program megállhat, visszautasíthatja a bemenetet, és esetleg felszólíthatja a felhasználót más bemenetre, ahelyett, hogy a program az érvénytelen túlcsordult bemenettel folytatná, és ennek következtében valószínűleg hibásan működne. Ez a teljes folyamat automatizálható: lehetséges automatikusan szintetizálni egy kezelőt egy egész szám túlcsordulására, ahol a kezelő például egy tiszta kilépés.

A CPU-k általában rendelkeznek egy olyan érzékelési módszerrel, amely támogatja a regiszterük méreténél nagyobb számok összeadását, általában egy állapotbit segítségével; ezt a technikát többszörös pontosságú aritmetikának nevezik.Így lehetséges két, egyenként két bájt széles számot összeadni csak bájtos összeadással, lépésekben: először az alacsony bájtok összeadása, majd a magas bájtok összeadása, de ha az alacsony bájtokból ki kell vinni, az a bájtos összeadás aritmetikai túlcsordulása, és szükségessé válik a magas bájtok összegének felismerése és inkrementálása.

A számítás esetleges túlcsordulásának kezelése néha választás elé állíthat, hogy a tényleges számítás előtt (annak megállapítására, hogy a túlcsordulás bekövetkezik-e vagy sem), vagy utána (annak mérlegelésére, hogy a kapott érték alapján valószínűsíthetően bekövetkezett-e vagy sem) végezzük el az ellenőrzést. Az utóbbi választással szemben óvatosnak kell lenni. Először is, mivel ez nem biztos, hogy megbízható észlelési módszer (például egy összeadás nem feltétlenül vezet alacsonyabb értékre). Másodszor, mert maga a túlcsordulás előfordulása bizonyos esetekben meghatározatlan viselkedés lehet. A C programozási nyelvben az előjel nélküli egész számtípusok túlcsordulása becsomagolást eredményez, azonban az előjeles egész számtípusok túlcsordulása nem meghatározott viselkedés; következésképpen a C fordító szabadon feltételezheti, hogy a programozó biztosította, hogy az előjeles túlcsordulás nem fordulhat elő, és így csendben optimalizálhat minden olyan, a számítást követő ellenőrzést, amely az eredmény ellenőrzését tartalmazza, anélkül, hogy figyelmeztetné a programozót, hogy ez megtörtént. Ezért célszerű az ellenőrzéseket mindig inkább a számítások előtt, mint utána megvalósítani.

Explicit propagationEdit

ha egy érték túl nagy ahhoz, hogy tárolni lehessen, akkor hozzá lehet rendelni egy speciális értéket, amely jelzi, hogy túlcsordulás történt, és ezután minden egymást követő művelet ezt a jelzőértéket adja vissza. Az ilyen értékeket néha NaN-nek nevezik, a “not a number” (nem szám) kifejezésre. Ez azért hasznos, hogy a problémát egyszer lehessen ellenőrizni egy hosszú számítás végén, nem pedig minden egyes lépés után. Ezt gyakran támogatják az FPU-nak nevezett lebegőpontos hardverek.

Programozási nyelvi támogatásSzerkesztés

A programozási nyelvek különböző enyhítési módszereket valósítanak meg a véletlen túlcsordulás ellen: Az Ada, a Seed7 (és a funkcionális nyelvek bizonyos változatai) túlcsorduláskor kivételi feltételt váltanak ki, míg a Python (2.4 óta) zökkenőmentesen alakítja át a szám belső reprezentációját a növekedésnek megfelelően, végül long-ként ábrázolja – aminek képességét csak a rendelkezésre álló memória korlátozza.

A tetszőleges pontosságú aritmetikát és típusbiztonságot natívan támogató nyelvekben (mint például a Python, a Smalltalk vagy a Common Lisp) a számok túlcsorduláskor automatikusan nagyobb méretre kerülnek, vagy tartománykorlátozás esetén kivételeket dobnak (feltételeket jeleznek). Az ilyen nyelvek használata tehát segíthet a probléma enyhítésében. Néhány ilyen nyelvben azonban még mindig előfordulhatnak olyan helyzetek, amikor egész számok túlcsordulása következhet be. Ilyen például egy olyan kódútvonal explicit optimalizálása, amelyet a profiler szűk keresztmetszetnek tekint. A Common Lisp esetében ez úgy lehetséges, hogy egy explicit deklarációval egy változót gépi méretű szóvá (fixnum) tipizálunk, és egy adott kódblokkban nullára csökkentjük a típusbiztonsági szintet.

A régebbi nyelvekkel, például a C-vel ellentétben néhány újabb nyelv, például a Rust, beépített funkciókkal rendelkezik, amelyek lehetővé teszik a túlcsordulás egyszerű felismerését, és a felhasználó eseti alapon eldöntheti, hogyan kezelje a túlcsordulást. A Rustban, bár az alapvető matematikai operátorok használata természetesen nélkülözi ezt a rugalmasságot, a felhasználók alternatívaként számításokat végezhetnek az egyes integer primitív típusok által biztosított metódusok segítségével. Ezek a metódusok többféle választási lehetőséget adnak a felhasználóknak egy “ellenőrzött” (vagy “túlcsorduló”) művelet végrehajtása (amely a visszatérési típuson keresztül jelzi, hogy történt-e túlcsordulás vagy sem); egy “nem ellenőrzött” művelet; egy olyan művelet, amely csomagolást végez, vagy egy olyan művelet, amely telítést végez a numerikus határoknál.

Telített aritmetikaEdit

A számítógépes grafikában vagy jelfeldolgozásban jellemző, hogy 0 és 1 vagy -1 és 1 közötti tartományba eső adatokkal dolgozunk. Vegyünk például egy szürkeárnyalatos képet, ahol a 0 a feketét, az 1 a fehéret, a kettő közötti értékek pedig a szürke árnyalatait jelentik. Az egyik művelet, amelyet támogatni szeretnénk, a kép világosabbá tétele azáltal, hogy minden egyes képpontot megszorozunk egy konstanssal. A telített aritmetika lehetővé teszi, hogy minden képpontot vakon megszorozzunk ezzel a konstanssal anélkül, hogy aggódnánk a túlcsordulás miatt, ha ragaszkodunk ahhoz az ésszerű eredményhez, hogy az összes ilyen 1-nél nagyobb (azaz “fehérnél világosabb”) képpont egyszerűen fehérré válik, és minden “feketénél sötétebb” érték egyszerűen feketévé válik.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.