Kokonaisluvun ylivuoto

.

Kokonaisluvun ylivuodon käsittely eri ohjelmointikielissä
Kieli Esimerkittömät kokonaisluvut Esimerkittömät kokonaisluvut
Ada modulo tyypin moduuli raise Constraint_Error
C/C++ modulo power of two undefined behavior
C# modulo power of 2 in unchecked context; System.OverflowException nostetaan tarkistetussa kontekstissa
Java N/A modulo kakkosen potenssi
JavaScript kaikki luvut ovat kaksinkertaisia-tarkkuuden liukulukuja paitsi uusi BigInt
MATLAB Builtin kokonaisluvut kyllästävät. Kiinteä-point integers konfiguroitavissa wrap tai saturate
Python 2 N/A muunnetaan long-tyyppisiksi. (bigint)
Seed7 N/A raise OVERFLOW_ERROR
Scheme N/A muunnetaan bigNumiksi
Simulink konfiguroitavissa käärimään tai kyllästämään
Smalltalk N/A konvertoi LargeIntegeriksi
Swift Syöttää virheen, ellei käytä erityisiä ylivuotooperaattoreita.

DetectionEdit

Ylivuodon havaitsemisen ajoaikainen toteutus UBSan on saatavilla C-kääntäjille.

Javassa 8 on ylikuormitettuja metodeja, esimerkiksi kuten Math.addExact(int, int), jotka heittävät ylivuodon sattuessa ArithmeticException.

Computer Emergency Response Team (CERT) kehitti As-if Infinitely Ranged (AIR) kokonaislukumallin, joka on pitkälti automatisoitu mekanismi, jolla voidaan eliminoida kokonaislukujen ylivuoto ja typistyminen C/C++:ssa käyttämällä ajonaikaista virheenkäsittelyä.

AvoidanceEdit

Varauttamalla muuttujia, joiden datatyypit ovat tarpeeksi suuria, jotta ne voivat pitää sisällään kaikki arvot, jotka voidaan mahdollisesti laskea ja tallettaa sinne, ylivuodon välttäminen on aina mahdollista. Jopa silloin, kun käytettävissä oleva tila tai ohjelmointikielen tai -ympäristön tarjoamat kiinteät tietotyypit ovat liian rajallisia, jotta muuttujille voitaisiin puolustautuvasti allokoida reilun kokoisia muuttujia, voidaan operaatioiden huolellisella järjestämisellä ja operandien tarkistamisella etukäteen usein varmistaa a priori, että tulos ei koskaan ole suurempi kuin voidaan tallentaa. Staattisia analyysityökaluja, muodollista verifiointia ja sopimussuunnittelutekniikoita voidaan käyttää varmemmin ja vankemmin varmistamaan, että ylivuotoa ei voi syntyä vahingossa.

HandlingEdit

Jos ylivuodon syntyminen on ennakoitavissa, ohjelmaan voidaan lisätä testejä, jotka havaitsevat, milloin ylivuoto tapahtuu tai on tapahtumassa, ja jotka suorittavat muuta käsittelyä ylivuodon lieventämiseksi. Jos esimerkiksi käyttäjän syötteestä laskettu tärkeä tulos ylikuormittuu, ohjelma voi pysähtyä, hylätä syötteen ja ehkä pyytää käyttäjää antamaan toisenlaisen syötteen sen sijaan, että ohjelma jatkaisi virheellisellä ylikuormittuneella syötteellä ja sen seurauksena todennäköisesti toimisi huonosti. Tämä koko prosessi voidaan automatisoida: on mahdollista syntetisoida automaattisesti käsittelijä kokonaisluvun ylivuotoa varten, jolloin käsittelijä on esimerkiksi puhdas poistuminen.

CPU:illa on yleensä tapa havaita tämä, jotta ne tukevat rekisterikokoa suurempien lukujen yhteenlaskemista, tyypillisesti statusbitin avulla; tekniikkaa kutsutaan monitarkkuusaritmiikaksi.On siis mahdollista laskea yhteen kaksi lukua, joista kumpikin on kaksi tavua leveä, käyttämällä pelkkää tavuadditiota vaiheittain: laske ensin matalat tavut yhteen ja laske sitten korkeat tavut yhteen, mutta jos matalista tavuista joudutaan viemään ulos, tämä on tavuaddition aritmeettinen ylivuoto, ja tulee tarpeelliseksi havaita ja kasvattaa korkeiden tavujen summaa.

Laskennan mahdollisen ylivuodon käsittely saattaa joskus asettaa vaihtoehdon sen välillä, suoritetaanko tarkistus ennen varsinaista laskentaa (sen selvittämiseksi, tapahtuuko ylivuoto) vai sen jälkeen (sen pohtimiseksi, tapahtuuko ylivuoto todennäköisesti tuloksena saadun arvon perusteella). Jälkimmäiseen vaihtoehtoon olisi suhtauduttava varovaisesti. Ensinnäkin siksi, että se ei välttämättä ole luotettava havaitsemismenetelmä (esimerkiksi yhteenlasku ei välttämättä kietoudu pienempään arvoon). Toiseksi, koska itse ylivuodon esiintyminen voi joissakin tapauksissa olla määrittelemätöntä käyttäytymistä. C-ohjelmointikielessä merkitsemättömien kokonaislukutyyppien ylivuoto johtaa kietoutumiseen, mutta merkityn kokonaislukutyypin ylivuoto on määrittelemätöntä käyttäytymistä; näin ollen C-kääntäjä voi vapaasti olettaa, että ohjelmoija on varmistanut, että merkityn kokonaisluvun ylivuotoa ei voi mahdollisesti esiintyä, ja näin ollen se voi optimoida äänettömästi pois kaikki laskennan jälkeiset tarkistukset, jotka edellyttävät tuloksen tarkistamista ylivuodon havaitsemiseksi, antamatta ohjelmoijalle minkäänlaista varoitusta siitä, että näin on tehty. On siis suositeltavaa toteuttaa tarkistukset aina mieluummin ennen laskutoimituksia kuin niiden jälkeen.

Eksplisiittinen eteneminenEdit

jos arvo on liian suuri tallennettavaksi, sille voidaan antaa erityinen arvo, joka ilmaisee, että ylivuoto on tapahtunut, ja sitten kaikki peräkkäiset operaatiot palauttavat tämän lippuarvon. Tällaisia arvoja kutsutaan joskus nimellä NaN, joka tarkoittaa ”not a number”. Tämä on hyödyllistä, jotta ongelma voidaan tarkistaa kerran pitkän laskutoimituksen lopussa eikä jokaisen vaiheen jälkeen. Tätä tuetaan usein liukulukulaitteistoissa, joita kutsutaan FPU:ksi.

Ohjelmointikielen tukiEdit

Ohjelmointikielet toteuttavat erilaisia lieventämismenetelmiä tahatonta ylivuotoa vastaan: Ada, Seed7 (ja tietyt funktionaalisten kielten variantit) laukaisevat poikkeusehdon ylivuodon sattuessa, kun taas Python (2.4:stä lähtien) muuntaa saumattomasti luvun sisäisen esityksen vastaamaan sen kasvua, esittäen sen lopulta muodossa long – jonka kykyä rajoittaa vain käytettävissä oleva muisti.

Kielissä, joissa on natiivituki mielivaltaisen tarkkuuden aritmetiikalle ja tyyppiturvallisuudelle (kuten Pythonissa, Smalltalkissa tai Common Lispissä), luvut siirretään automaattisesti suurempaan kokoon ylivuodon tapahtuessa, tai poikkeuksia heitetään (ehdoista ilmoitetaan), kun on olemassa vaihtelualuerajoitus. Tällaisten kielten käyttö voi siis olla hyödyllistä tämän ongelman lieventämiseksi. Joissakin tällaisissa kielissä on kuitenkin edelleen mahdollisia tilanteita, joissa kokonaisluvun ylivuoto voi tapahtua. Esimerkkinä voidaan mainita sellaisen koodipolun eksplisiittinen optimointi, jota profiloija pitää pullonkaulana. Common Lispissä tämä on mahdollista käyttämällä eksplisiittistä julistusta muuttujan tyyppi-merkitsemiseksi konekokoiseksi sanaksi (fixnum) ja alentamalla tyyppiturvallisuustaso nollaan tietyssä koodilohkossa.

Täysin päinvastoin kuin vanhemmissa kielissä, kuten C:ssä, joissakin uudemmissa kielissä, kuten esimerkiksi Rustissa, on sisäänrakennettu toiminto, joka mahdollistaa helpon havaitsemisen ja käyttäjän valinnan siitä, miten ylivuotoa pitäisi käsitellä tapauskohtaisesti. Vaikka Rustissa matemaattisten perusoperaattoreiden käytöstä puuttuu luonnollisesti tällainen joustavuus, käyttäjät voivat vaihtoehtoisesti suorittaa laskutoimituksia kunkin kokonaislukutyypin tarjoamien metodien avulla. Nämä metodit antavat käyttäjille useita vaihtoehtoja: suorittaa ”tarkistettu” (tai ”ylivuotava”) operaatio (joka ilmoittaa paluutyypin avulla, tapahtuiko ylivuoto vai ei), ”tarkistamaton” operaatio, operaatio, joka suorittaa käärimisen, tai operaatio, joka suorittaa kyllästämisen numeeristen rajojen kohdalla.

Kyllästetty aritmetiikkaMuutos

Tietokonegrafiikassa tai signaalinkäsittelyssä on tyypillistä työskennellä datan parissa, joka vaihtelee 0:n ja 1:n välillä tai -1:stä 1:een. Otetaan esimerkiksi harmaasävykuva, jossa 0 edustaa mustaa, 1 edustaa valkoista ja siltä väliltä olevat arvot edustavat harmaan sävyjä. Yksi operaatio, jota saatetaan haluta tukea, on kuvan kirkastaminen kertomalla jokainen pikseli vakiolla. Kyllästetyn aritmetiikan avulla voidaan sokeasti kertoa jokainen pikseli tuolla vakiolla huolehtimatta ylivuodosta pitäytymällä kohtuullisessa lopputuloksessa, jonka mukaan kaikista näistä pikseleistä, jotka ovat suurempia kuin 1 (eli ”valkoista kirkkaammat”), tulee vain valkoisia ja kaikista arvoista, jotka ovat ”mustaa tummempia”, tulee vain mustia.

Vastaa

Sähköpostiosoitettasi ei julkaista.