Přetečení celého čísla

Ošetření přetečení celého čísla v různých programovacích jazycích
Jazyk Celé číslo bez znaménka Celé číslo se znaménkem
Ada modulo modul typu vyvolá Constraint_Error
C/C++ modulo mocnina dvou nedefinované chování
C# modulo mocnina 2 v nekontrolovaném kontextu; System.OverflowException v zaškrtnutém kontextu se zvýší
Java N/A modulo mocnina dvou
JavaScript všechna čísla jsou dvoj-přesnosti s plovoucí desetinnou čárkou kromě nového BigInt
MATLAB Builtin integers saturate. Pevně-point integers konfigurovatelné pro obalení nebo nasycení
Python 2 N/A převod na typ long (bigint)
Seed7 N/A raise OVERFLOW_ERROR
Scheme N/A převést na bigNum
Simulink konfigurovatelný na zabalení nebo nasycení
Smalltalk N/A převést na LargeInteger
Swift Způsobuje chybu, pokud nejsou použity speciální operátory přetečení.

DetectionEdit

Implementace detekce přetečení za běhu UBSan je k dispozici pro kompilátory jazyka C.

V Javě 8 existují přetížené metody, například jako Math.addExact(int, int), které v případě přetečení vyhodí ArithmeticException.

Computer emergency response team (CERT) vyvinul celočíselný model As-if Infinitely Ranged (AIR), což je do značné míry automatizovaný mechanismus pro eliminaci přetečení a zkrácení celých čísel v jazyce C/C++ pomocí ošetření chyb za běhu.

AvoidanceEdit

Alokováním proměnných s datovými typy, které jsou dostatečně velké, aby se do nich vešly všechny hodnoty, které mohou být případně vypočteny a uloženy, je vždy možné zabránit přetečení. I když je dostupný prostor nebo pevné datové typy poskytované programovacím jazykem nebo prostředím příliš omezené na to, aby bylo možné defenzivně alokovat proměnné s velkorysou velikostí, pečlivým řazením operací a předběžnou kontrolou operandů lze často a priori zajistit, že výsledek nebude nikdy větší, než lze uložit. Nástroje statické analýzy, formální verifikace a techniky návrhu podle smlouvy lze použít k jistějšímu a robustnějšímu zajištění toho, že nemůže náhodně dojít k přetečení.

HandlingEdit

Pokud se předpokládá, že může dojít k přetečení, pak lze do programu vložit testy, které zjistí, kdy k němu dojde nebo má dojít, a provedou další zpracování k jeho zmírnění. Pokud například dojde k přetečení důležitého výsledku vypočteného z uživatelského vstupu, může se program zastavit, odmítnout vstup a třeba vyzvat uživatele k jinému vstupu, místo aby program pokračoval s neplatným přetečeným vstupem a v důsledku toho pravděpodobně špatně fungoval. Celý tento proces lze automatizovat: je možné automaticky syntetizovat obslužný program pro přetečení celého čísla, kde obslužným programem je například čisté ukončení.

CPU mají obecně způsob detekce, který podporuje sčítání čísel větších, než je velikost jejich registru, obvykle pomocí stavového bitu; tato technika se nazývá aritmetika s násobnou přesností.Je tedy možné sčítat dvě čísla, každé o šířce dvou bajtů, pomocí pouhého sčítání bajtů v krocích: nejprve sečteme nízké bajty, pak sečteme vysoké bajty, ale pokud je nutné provést z nízkých bajtů, jedná se o aritmetické přetečení sčítání bajtů a je nutné detekovat a inkrementovat součet vysokých bajtů.

Řešení možného přetečení výpočtu může někdy představovat volbu mezi provedením kontroly před vlastním výpočtem (pro zjištění, zda k přetečení dojde), nebo po něm (pro zvážení, zda k němu pravděpodobně došlo na základě výsledné hodnoty). K druhé volbě je třeba přistupovat obezřetně. Zaprvé proto, že nemusí jít o spolehlivou metodu detekce (například sčítání se nemusí nutně zabalit do nižší hodnoty). Za druhé proto, že samotný výskyt přetečení může být v některých případech nedefinovaným chováním. V programovacím jazyce C má přetečení celočíselných typů bez znaménka za následek obalení, avšak přetečení celočíselných typů se znaménkem je nedefinované chování; překladač jazyka C proto může předpokládat, že programátor zajistil, aby k přetečení se znaménkem nemohlo dojít, a proto může v tichosti optimalizovat jakoukoli následnou kontrolu výpočtu, která zahrnuje kontrolu výsledku za účelem jeho detekce, aniž by programátora upozornil, že k tomu došlo. Je tedy vhodné vždy raději implementovat kontroly před výpočty, nikoli po nich.

Explicitní propagaceEdit

pokud je hodnota příliš velká na to, aby mohla být uložena, lze jí přiřadit speciální hodnotu indikující, že došlo k přetečení, a pak nechat všechny následující operace vracet tuto hodnotu příznaku. Takové hodnoty se někdy označují jako NaN, což znamená „není číslo“. To je užitečné proto, aby bylo možné problém zkontrolovat jednou na konci dlouhého výpočtu, a ne po každém kroku. To je často podporováno v hardwaru s plovoucí desetinnou čárkou zvaném FPU.

Podpora programovacích jazykůUpravit

Programovací jazyky implementují různé metody zmírnění rizika náhodného přetečení: Ada, Seed7 (a některé varianty funkcionálních jazyků) vyvolávají při přetečení podmínku výjimky, zatímco Python (od verze 2.4) plynule převádí vnitřní reprezentaci čísla tak, aby odpovídala jeho růstu, případně jej reprezentuje jako long – jehož schopnost je omezena pouze dostupnou pamětí.

V jazycích s nativní podporou aritmetiky s libovolnou přesností a typovou bezpečností (jako je Python, Smalltalk nebo Common Lisp) jsou čísla při přetečení automaticky povýšena na větší velikost nebo jsou při existenci omezení rozsahu vyhazovány výjimky (signalizovány podmínky). Použití takových jazyků tedy může být užitečné pro zmírnění tohoto problému. V některých takových jazycích jsou však stále možné situace, kdy může dojít k přetečení celého čísla. Příkladem je explicitní optimalizace cesty kódu, kterou profiler považuje za úzké místo. V případě jazyka Common Lisp je to možné pomocí explicitní deklarace pro typovou anotaci proměnné na slovo strojové velikosti (fixnum) a snížení úrovně typové bezpečnosti na nulu pro konkrétní blok kódu.

Na rozdíl od starších jazyků, jako je C, některé novější jazyky, jako je například Rust, poskytují vestavěnou funkci, která umožňuje snadnou detekci a volbu uživatele, jak má být přetečení řešeno případ od případu. V jazyce Rust sice použití základních matematických operátorů takovou flexibilitu přirozeně postrádá, uživatelé však mohou alternativně provádět výpočty prostřednictvím sady metod poskytovaných každým z celočíselných primitivních typů. Tyto metody dávají uživatelům několik možností volby mezi provedením „kontrolované“ (nebo „přetečení“) operace (která prostřednictvím návratového typu indikuje, zda k přetečení došlo, či nikoli); „nekontrolované“ operace; operace, která provádí obalení, nebo operace, která provádí nasycení na hranicích čísel.

Nasycená aritmetikaEdit

V počítačové grafice nebo při zpracování signálů je typické pracovat s daty, která se pohybují v rozmezí od 0 do 1 nebo od -1 do 1.

Nasycená aritmetikaEdit

V počítačové grafice nebo při zpracování signálů je typické pracovat s daty, která se pohybují v rozmezí od 0 do 1. Vezměme například obrázek ve stupních šedi, kde 0 představuje černou, 1 bílou a hodnoty mezi nimi představují odstíny šedé. Jednou z operací, kterou můžeme chtít podporovat, je zesvětlení obrazu vynásobením každého pixelu konstantou. Sytá aritmetika umožňuje prostě naslepo vynásobit každý pixel touto konstantou bez obav z přetečení tím, že se prostě přidržíme rozumného výsledku, že všechny tyto pixely větší než 1 (tj. „světlejší než bílá“) se prostě stanou bílými a všechny hodnoty „tmavší než černá“ se prostě stanou černými.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.