Voor welke nummers wordt ondertekende weergave gebruikt? Drijvende-komma-indeling

Doel van de dienst. De online rekenmachine is ontworpen om reële getallen in drijvende-komma-indeling weer te geven.

Nummer

vertegenwoordigd in het 10 2-nummersysteem.
Vertegenwoordig het getal in:
genormaliseerde exponentiële vorm
gedenormaliseerde exponentiële vorm
32-bits IEEE 754-formaat
64-bits IEEE 754-formaat
Converteer terug naar decimale notatie

Regels voor het invoeren van cijfers

  1. Getallen in het decimale getallensysteem kunnen zonder breuk of met worden ingevoerd fractioneel deel (234234.455).
  2. Nummers binnen binair systeem De cijfers bestaan ​​alleen uit de cijfers 0 en 1 (10100.01).
  3. Getallen in het hexadecimale getallensysteem bestaan ​​uit de cijfers 0...9 en de letters A...F.
  4. U kunt ook de omgekeerde weergave van de code krijgen (vanaf hexadecimaal systeem decimale berekening, 40B00000)
Voorbeeld nr. 1. Geef het getal 133,54 weer in drijvende-kommavorm.
Oplossing. Laten we het getal 133,54 in genormaliseerde exponentiële vorm weergeven:
1,3354*10 2 = 1,3354*exp 10 2
Het getal 1,3354*exp 10 2 bestaat uit twee delen: de mantisse M=1,3354 en de exponent exp 10 =2
Als de mantisse zich in het bereik 1 ≤ M bevindt Weergave van een getal in gedenormaliseerde exponentiële vorm.
Als de mantisse zich in het bereik 0,1 ≤ M bevindt, stellen we het getal in gedenormaliseerde exponentiële vorm voor: 0,13354*exp 10 3

Voorbeeld nr. 2. Vertegenwoordigt het binaire getal 101.10 2 in genormaliseerde vorm, geschreven in de 32-bits IEEE754-standaard.
Oplossing.
Weergave van een binair getal met drijvende komma in exponentieel genormaliseerde vorm.
Laten we het getal 2 cijfers naar rechts verschuiven. Als resultaat hebben we de belangrijkste componenten van een exponentieel genormaliseerd binair getal verkregen:
Mantisse M=1,011
Exponent exp 2 =2
Converteer binair genormaliseerd getal naar 32-bits IEEE 754-formaat.
Het eerste bit wordt toegewezen om het teken van het getal aan te geven. Omdat het getal positief is, is het eerste bit 0
De volgende 8 bits (2e tot en met 9e) zijn gereserveerd voor de exponent.
Om het teken van de exponent te bepalen, om niet nog een tekenbit te introduceren, voegt u een offset toe aan de exponent van een halve byte +127. Onze exponent is dus: 2 + 127 = 129
Laten we de exponent omzetten naar binaire representatie.
De overige 23 bits zijn gereserveerd voor de mantisse. In een genormaliseerde binaire mantisse is het eerste bit altijd gelijk aan 1, aangezien het getal in het bereik 1 ≤ M ligt. Om het gehele deel te converteren, moet je het cijfer van het getal vermenigvuldigen met de overeenkomstige cijfermacht.
01100000000000000000000 = 2 22 *0 + 2 21 *1 + 2 20 *1 + 2 19 *0 + 2 18 *0 + 2 17 *0 + 2 16 *0 + 2 15 *0 + 2 14 *0 + 2 13 *0 + 2 12 *0 + 2 11 *0 + 2 10 *0 + 2 9 *0 + 2 8 *0 + 2 7 *0 + 2 6 *0 + 2 5 *0 + 2 4 *0 + 2 3 *0 + 2 2 *0 + 2 1 *0 + 2 0 *0 = 0 + 2097152 + 1048576 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 3145728
IN decimale code De mantisse wordt uitgedrukt als 3145728
Als gevolg hiervan is het getal 101.10, weergegeven in IEEE 754 met enkele precisie, gelijk aan.
Laten we converteren naar hexadecimale weergave.
Laten we verdelen broncode in groepen van 4 categorieën.
2 = 0100 0000 1011 0000 0000 0000 0000 0000 2
We krijgen het nummer:
0100 0000 1011 0000 0000 0000 0000 0000 2 = 40B00000 16

In de oudheid, voor de IT-industrie was dit de jaren ’70 van de vorige eeuw, vochten wiskundigen (zoals programmeurs vroeger werden genoemd) net als Don Quixotes in een ongelijke strijd met computers, die toen zo groot waren als kleine windmolens. De taken waren serieus: zoeken naar vijandelijke onderzeeërs in de oceaan met behulp van beelden uit de ruimte, het berekenen van raketballistiek lange afstand, enzovoort. Om ze op te lossen moet de computer werken met reële getallen, die, zoals we weten, een continuüm vormen, terwijl het geheugen eindig is. Daarom moeten we dit continuüm in kaart brengen op een eindige reeks nullen en enen. Op zoek naar een compromis tussen snelheid, omvang en nauwkeurigheid van representatie, stelden wetenschappers drijvende-kommagetallen voor (of drijvende-komma, als dat in de burgerij bestond).

Drijvende-komma-rekenkunde wordt op de een of andere manier beschouwd als een exotisch gebied van de informatica, aangezien de overeenkomstige gegevenstypen in elke programmeertaal aanwezig zijn. Om eerlijk te zijn, heb ik nooit veel belang gehecht aan computerrekenkunde, terwijl ik bij het oplossen van hetzelfde probleem op de CPU en GPU verschillende resultaten kreeg. Het bleek dat er in de geheime hoeken van dit gebied zeer merkwaardige en vreemde verschijnselen verborgen zijn: niet-commutativiteit en niet-associativiteit rekenkundige bewerkingen, nul met een teken, het verschil tussen ongelijke getallen levert nul op, enzovoort. De wortels van deze ijsberg liggen diep in de wiskunde, en onder de snede zal ik proberen alleen te schetsen wat aan de oppervlakte ligt.

1. Basisprincipes

De reeks gehele getallen is oneindig, maar we kunnen altijd een aantal bits kiezen om elk geheel getal weer te geven dat ontstaat bij het oplossen specifieke taak. De reeks reële getallen is niet alleen oneindig, maar ook continu, dus hoeveel bits we ook nemen, we zullen onvermijdelijk getallen tegenkomen die geen exacte representatie hebben. Drijvende-kommagetallen zijn er één van mogelijke manieren weergave van reële getallen, wat een afweging is tussen nauwkeurigheid en bereik van geaccepteerde waarden.

Een getal met drijvende komma bestaat uit een reeks individuele cijfers, conventioneel verdeeld in teken, exponent en mantisse. De exponent en mantisse zijn gehele getallen die, samen met het teken, de volgende weergave van een drijvende-kommagetal geven:

Wiskundig gezien wordt het als volgt geschreven:

(-1) s × M × B E, waarbij s het teken is, B de wortel is, E de exponent is en M de mantisse is.

De basis bepaalt het cijfersysteem. Het is wiskundig bewezen dat drijvende-kommagetallen met grondtal B=2 (binaire representatie) het meest resistent zijn tegen afrondingsfouten, daarom komen we in de praktijk alleen grondtal 2 en, minder gebruikelijk, 10 tegen. Voor verdere presentatie gaan we altijd uit van B= 2, en de formule voor een getal met drijvende komma ziet er als volgt uit:

(-1) s × M × 2 E

Wat is mantisse en orde? Mantisse is een geheel getal met een vaste lengte dat de meest significante bits van een reëel getal vertegenwoordigt. Laten we zeggen dat onze mantisse uit drie bits bestaat (|M|=3). Neem bijvoorbeeld het getal “5”, dat in het binaire systeem gelijk is aan 101 2. Het meest significante bit komt overeen met 2 2 =4, het middelste bit (dat gelijk is aan nul) is 2 1 =2, en het minst significante bit is 2 0 =1. Volgorde– dit is de macht van het grondtal (twee) van het hoogste cijfer. In ons geval E=2. Het is handig om dergelijke getallen in de zogenaamde ‘wetenschappelijke’ te schrijven standaard formulier, bijvoorbeeld "1.01e+2". Het is meteen duidelijk dat de mantisse uit drie tekens bestaat, en de volgorde is twee.

Laten we zeggen dat we willen krijgen fractioneel getal, met behulp van dezelfde 3 stukjes van de mantisse. Dit kunnen we doen als we bijvoorbeeld E=1 nemen. Dan zal ons aantal gelijk zijn

1,01e+1 = 1×2 1 +0×2 0 +1×2 -1 =2+0,5=2,5

Aangezien E=1 is de macht van twee van het eerste cijfer (dat vóór de komma komt) hier “1”. De andere twee cijfers aan de rechterkant (na de komma) geven een bijdrage van 2 E-1 en 2 E-2 (respectievelijk 2 0 en 2 -1). Het is duidelijk dat door E aan te passen hetzelfde getal op verschillende manieren kan worden weergegeven. Laten we een voorbeeld bekijken met de lengte van de mantisse |M|=4. Het getal “2” kan als volgt worden weergegeven:

2 = 10 (in binair getal) = 1.000e+1 = 0.100e+2 = 0.010e+3. (respectievelijk E=1, E=2, E=3)

Houd er rekening mee dat hetzelfde nummer meerdere weergaven heeft. Dit is niet handig voor de apparatuur, omdat... het is noodzakelijk om rekening te houden met de veelheid van representaties bij het vergelijken van getallen en bij het uitvoeren van rekenkundige bewerkingen daarop. Bovendien is het niet economisch, aangezien het aantal representaties eindig is en herhaling het aantal getallen vermindert dat überhaupt kan worden weergegeven. Daarom begonnen ze al bij de allereerste machines een truc te gebruiken, waardoor het eerste stukje van de mantisse altijd positief werd. Deze presentatie heette genormaliseerd.

Dit bespaart één bit omdat de impliciete niet in het geheugen hoeft te worden opgeslagen en zorgt ervoor dat het getal uniek wordt weergegeven. In ons voorbeeld heeft “2” een enkele genormaliseerde representatie (“1.000e+1”), en wordt de mantisse in het geheugen opgeslagen als “000”, omdat hogere eenheid impliciet impliciet. Maar in de genormaliseerde weergave van getallen ontstaat er nieuw probleem- het is onmogelijk om nul in deze vorm weer te geven.

Strikt genomen heeft een genormaliseerd getal de volgende vorm:

(-1) s × 1,M × 2 E .

De kwaliteit van het oplossen van problemen hangt grotendeels af van de keuze voor drijvende-kommaweergave. Geleidelijk benaderden we het probleem van het standaardiseren van een dergelijke representatie.

2. Een beetje geschiedenis

In de jaren zestig en zeventig bestond er geen enkele standaard voor het weergeven van drijvende-kommagetallen, afrondingsmethoden of rekenkundige bewerkingen. Als gevolg hiervan waren de programma's uiterst ondraagbaar. Maar toch groter probleem had wat verschillende computers er waren enkele “eigenaardigheden” en die moesten bekend zijn en er moest rekening mee gehouden worden in het programma. Het verschil tussen twee ongelijke getallen leverde bijvoorbeeld nul op. Als gevolg hiervan kwamen de uitdrukkingen “X=Y” en “X-Y=0” met elkaar in conflict. Vaklieden omzeilden dit probleem met zeer slimme trucs, bijvoorbeeld door de opdracht “X=(X-X)+X” te geven vóór vermenigvuldigings- en delingsoperaties om problemen te voorkomen.

Het initiatief om één enkele standaard te creëren voor het weergeven van drijvende-kommagetallen viel verdacht veel samen met pogingen van Intel in 1976 om ‘betere’ rekenkunde te ontwikkelen voor de nieuwe 8086- en i432-coprocessors. De ontwikkeling werd uitgevoerd door wetenschappers op dit gebied, prof. John Palmer en William Kahan. Laatstgenoemde uitte in een interview de mening dat de ernst waarmee Intel zijn rekenkunde ontwikkelde andere bedrijven dwong zich te verenigen en het standaardisatieproces te beginnen.

Iedereen was serieus, omdat het zeer winstgevend is om je architectuur te promoten en standaard te maken. De bedrijven DEC, National Superconductor, Zilog en Motorola presenteerden hun voorstellen. Mainframemakers Cray en IBM keken vanaf de zijlijn toe. Intel-bedrijf, presenteerde natuurlijk ook haar nieuwe rekenkunde. De auteurs van de voorgestelde specificatie waren William Kahan, Jeromy Kunen en Harold Stone, en hun voorstel kreeg onmiddellijk de bijnaam “KCS”.

Vrijwel onmiddellijk werden op twee na alle voorstellen afgewezen: VAX van DEC en "KCS" van Intel. De VAX-specificatie was veel eenvoudiger, deze was al geïmplementeerd in PDP-11-computers en het was duidelijk hoe je deze kon verkrijgen maximale prestaties. Aan de andere kant bevatte "KCS" veel nuttige functionaliteit, zoals "speciale" en "gedenormaliseerde" nummers (details hieronder).

Alles in K-C-S rekenkundige algoritmen zijn strikt gespecificeerd en het is vereist dat het resultaat bij de implementatie daarmee samenvalt. Hierdoor kunnen binnen deze specificatie strikte berekeningen worden gemaakt. Als een wiskundige eerder een probleem oploste met behulp van numerieke methoden en de eigenschappen van de oplossing bewees, was er geen garantie dat deze eigenschappen in het programma behouden zouden blijven. De nauwkeurigheid van de KCS-rekenkunde maakte het mogelijk om stellingen te bewijzen met behulp van drijvende-kommaberekeningen.

DEC heeft er alles aan gedaan om van zijn specificatie een standaard te maken. Ze riep zelfs de steun in van enkele gerenommeerde wetenschappers dat de rekenkunde van KCS in principe niet dezelfde prestaties zou kunnen leveren als DEC. De ironie is dat Intel wist hoe hij zijn specificaties performant moest maken, maar deze trucs waren een bedrijfsgeheim. Als Intel niet had toegegeven en enkele van zijn geheimen had onthuld, zou het de aanval van DEC niet hebben kunnen tegenhouden.

Voor meer informatie over de standaardisatiestrijd, zie het interview van professor Kahan, en we zullen kijken hoe drijvende-kommaweergave er nu uitziet.

3. Weergave van drijvende-kommagetallen vandaag

De KCS-ontwikkelaars wonnen en nu is hun geesteskind de IEEE754-standaard geworden. Het vertegenwoordigt getallen met drijvende komma als teken (s), mantisse (M) en exponent (E) als volgt:

(-1)s × 1,M × 2 E

Opmerking. In de nieuwe IEE754-2008 standaard staan ​​naast getallen met grondtal 2 ook getallen met grondtal 10, de zogenaamde decimale(decimale) getallen met drijvende komma.

Om de lezer niet te overweldigen met overmatige informatie die op Wikipedia te vinden is, beschouwen we slechts één gegevenstype, namelijk enkele precisie (float). Getallen met halve, dubbele en uitgebreide precisie hebben dezelfde kenmerken, maar hebben een ander bereik van volgorde en mantisse. Bij getallen met enkele precisie (float/single) bestaat de volgorde uit 8 bits en de mantisse uit 23. De effectieve volgorde wordt gedefinieerd als E-127. Het getal 0,15625 zou bijvoorbeeld in het geheugen worden opgeslagen als

Foto overgenomen van Wikipedia

In dit voorbeeld:

  • Teken s=0 (positief getal)
  • Bestel E=01111100 2 -127 10 = -3
  • Mantisse M = 1,01 2 (eerste eenheid is niet expliciet)
  • Als gevolg hiervan is ons getal F = 1,01 2 e-3 = 2 -3 +2 -5 = 0,125 + 0,03125 = 0,15625

Iets uitgebreidere uitleg

Hier hebben we te maken met een binaire weergave van het getal “101” waarbij de komma enkele plaatsen naar links is verschoven. 1.01 is een binaire representatie, wat betekent 1×2 0 + 0×2 -1 + 1×2 -2 . Als we de komma drie posities naar links verschuiven, krijgen we 1×2 -3 + 0×2 -4 + 1×2 -5 = 1×0,125 + 0×0,0625 + 1×0,03125 = 0,125 + 0 . 03125 = 0,15625.

3.1 Speciale getallen: nul, oneindig en onzekerheid
In IEEE754 wordt het getal "0" weergegeven door een waarde met een orde gelijk aan E=E min -1 (voor single is dit -127) en een nul-mantisse. De introductie van nul als onafhankelijk getal (aangezien nul niet kan worden weergegeven in een genormaliseerde representatie) maakte het mogelijk om veel eigenaardigheden in de rekenkunde te vermijden. En hoewel bewerkingen met nul afzonderlijk moeten worden verwerkt, worden ze meestal sneller uitgevoerd dan met reguliere getallen.

IEEE754 biedt ook een weergave voor speciale nummers, waarvan de werking een uitzondering veroorzaakt. Deze getallen omvatten oneindigheid (±∞) en onzekerheid (NaN). Met deze cijfers kunt u een adequate waarde retourneren in geval van overloop. Oneindigheden worden weergegeven als getallen met de volgorde E=E max +1 en mantisse nul. Je kunt oneindig krijgen door overloop en door een getal dat niet nul is, te delen door nul. De ontwikkelaars hebben de oneindigheid van de deling bepaald op basis van het bestaan ​​van limieten wanneer het deeltal en de deler naar een bepaald getal neigen. Dienovereenkomstig geldt c/0==±∞ (bijvoorbeeld 3/0=+∞ en -3/0=-∞), want als het deeltal naar een constante neigt en de deler naar nul neigt, is de limiet is gelijk aan oneindig. Bij 0/0 is er geen limiet, dus het resultaat zal onzekerheid zijn.

Onzekerheid of NaN (van niet een getal) is een representatie die is uitgevonden zodat een rekenkundige bewerking altijd een niet-betekenisvolle waarde kan retourneren. In IEEE754 wordt NaN weergegeven als een getal waarin E=E max +1 en de mantisse niet nul is. Elke bewerking met NaN retourneert NaN. Indien gewenst kunt u informatie in de mantisse schrijven die het programma kan interpreteren. Dit wordt niet gespecificeerd door de standaard en de mantisse wordt meestal genegeerd.

Hoe kun je NaN krijgen? Op een van de volgende manieren:

  • ∞+(- ∞)
  • 0 × ∞
  • 0/0, ∞/∞
  • sqrt(x), waarbij x<0
Per definitie is NaN ≠ NaN. Om de waarde van een variabele te controleren, hoeft u deze dus alleen maar met zichzelf te vergelijken.
Waarom heeft nul een teken (of +0 versus -0)
De nieuwsgierige lezer heeft waarschijnlijk al gemerkt dat er in de beschreven weergave van getallen met drijvende komma twee nullen voorkomen die alleen qua teken verschillen. Dus 3·(+0)=+0, en 3·(-0)=-0. Maar als je +0=-0 vergelijkt. In de standaard werd het teken bewust behouden, zodat uitdrukkingen die als gevolg van overloop of onderloop in oneindig of nul veranderen, ook bij vermenigvuldiging en deling nog steeds het meest correcte resultaat konden opleveren. Als nul bijvoorbeeld geen teken zou hebben, zou de uitdrukking 1/(1/x)=x niet waar zijn bij x=±∞, aangezien 1/∞ en 1/-∞ gelijk zijn aan 0.

Nog een voorbeeld:
(+∞/0) + ∞ = +∞, terwijl (+∞/-0) +∞ = NaN

Waarom is oneindigheid in dit geval beter dan NaN? Want als NaN in een rekenkundige uitdrukking voorkomt, zal het resultaat van de gehele uitdrukking altijd NaN zijn. Als oneindig in de uitdrukking wordt aangetroffen, kan het resultaat nul, oneindig of een gewoon getal met drijvende komma zijn. Bijvoorbeeld 1/∞=0.

3.3 Gedenormaliseerde getallen
Laten we eens kijken naar welke subnormale, gedenormaliseerde getallen een eenvoudig voorbeeld gebruiken. Laten we een genormaliseerde representatie hebben met een mantisselengte |M|=2 bits (+ één bit normalisatie) en een bereik van waarden in de orde van -1≤E≤2. In dit geval krijgen we 16 cijfers:

Grote lijnen tonen getallen met een mantisse gelijk aan 1,00. Het is duidelijk dat de afstand van nul tot het dichtstbijzijnde getal (0 - 0,5) groter is dan van dit getal tot het volgende (0,5 - 0,625). Dit betekent dat het verschil tussen twee willekeurige getallen van 0,5 tot 1 0 oplevert, zelfs als deze getallen niet gelijk zijn. Wat nog erger is, is dat het verschil tussen getallen groter dan 1 in het gat tussen 0,5 en 0 valt. Bijvoorbeeld: “1,5-1,25=0” (zie afbeelding).

Niet elk programma valt in het ‘bijna-nulgat’. Volgens statistieken uit de jaren '70 ondervond elke computer dit probleem gemiddeld één keer per maand. Gezien het feit dat computers wijdverbreid raakten, vonden de KCS-ontwikkelaars dit probleem ernstig genoeg om op hardwareniveau op te lossen. De oplossing die zij voorstelden was als volgt. We weten dat met E=E min -1 (voor float is dit “-127”) en een mantisse nul, het getal als gelijk aan nul wordt beschouwd. Als de mantisse niet nul is, wordt het getal beschouwd als niet nul, wordt de volgorde ervan ingesteld op E=Emin, en wordt de impliciete hoge bit van de mantisse op nul gezet. Dergelijke nummers worden gebeld gedenormaliseerd.

Strikt genomen zien drijvende-kommagetallen er nu als volgt uit:

(-1) s × 1,M × 2 E als E min ≤E≤E max (genormaliseerde getallen)

(-1) s × 0,M × 2 Emin als E=E min -1. (gedenormaliseerde getallen)

Laten we teruggaan naar het voorbeeld. Onze E min =-1. Laten we een nieuwe ordewaarde introduceren, E=-2, waarbij de getallen worden gedenormaliseerd. Als gevolg hiervan krijgen we een nieuwe weergave van getallen:

Het interval van 0 tot 0,5 is gevuld met gedenormaliseerde getallen, wat het mogelijk maakt om niet te falen in de hierboven besproken 0-voorbeelden (0,5-0,25 en 1,5-1,25). Dit maakte de representatie robuuster voor afrondingsfouten voor getallen dichtbij nul.

Maar de luxe van het gebruik van een gedenormaliseerde weergave van getallen in de processor is niet gratis. Omdat dergelijke getallen bij alle rekenkundige bewerkingen anders moeten worden afgehandeld, is het moeilijk om dergelijke rekenkundige handelingen efficiënt te laten verlopen. Dit brengt extra problemen met zich mee bij het implementeren van ALU's in de processor. En hoewel gedenormaliseerde getallen erg nuttig zijn, zijn ze geen wondermiddel en moet er nog steeds voor afronding naar nul worden gezorgd. Deze functionaliteit werd dan ook een struikelblok tijdens de ontwikkeling van de standaard en stuitte op de grootste weerstand.

3.4 Nummervolgorde in IEEE754
Een van de verbazingwekkende kenmerken van de IEEE754 getalrepresentatie is dat de exponent en de mantisse zo achter elkaar zijn gerangschikt dat ze samen een reeks gehele getallen (n) vormen waarvoor het volgende geldt:

N

Dus als we een positief getal met drijvende komma nemen, dit omzetten in een geheel getal en '1' toevoegen, krijgen we het volgende getal dat in deze rekenkunde kan worden weergegeven. In C kun je het als volgt doen:

Vlotter a=0,5; int n = *((int*) &a); zweven b = *((zweven*) &(++n)); printf("Na %e het volgende getal: %e, verschil (%e)\n", a, b, b-a);
Deze code werkt alleen op een 32-bits int-architectuur.

4. Valkuilen bij het rekenen met drijvende komma

Nu - om te oefenen. Laten we eens kijken naar de kenmerken van drijvende-kommaberekeningen die speciale aandacht vereisen bij het programmeren.
4.1 Afronding
Fouten als gevolg van afrondingsfouten zijn moeilijk tegen te komen in de moderne drijvende-kommaberekeningen, vooral bij gebruik van dubbele precisie. De afrondingsregel in de IEEE754-standaard stelt dat het resultaat van elke rekenkundige bewerking moet zijn alsof deze is uitgevoerd op de exacte waarden en moet worden afgerond op het dichtstbijzijnde getal dat in dat formaat kan worden weergegeven. Dit vereist extra inspanning van de ALU, en sommige compileropties (zoals "-ffast-math" in gcc) kunnen dit gedrag uitschakelen. IEEE754 afrondingsfuncties:
  • Het afronden naar het dichtstbijzijnde in de standaard gebeurt anders dan we gewend zijn. Het is wiskundig aangetoond dat als 0,5 wordt afgerond naar 1 (naar boven), er een reeks bewerkingen bestaat waarbij de afrondingsfout toeneemt tot oneindig. Daarom gebruikt IEEE754 de round-to-even-regel. Dus 12,5 wordt afgerond naar 12 en 13,5 wordt afgerond naar 14.
  • De gevaarlijkste bewerking in termen van afronding in drijvende-kommaberekeningen is aftrekken. Bij het aftrekken van nauwe cijfers kunnen significante cijfers verloren gaan
    kan de relatieve fout verschillende keren vergroten.
  • Voor veel veelgebruikte wiskundige formules hebben wiskundigen een speciale vorm ontwikkeld die afrondingsfouten aanzienlijk kan verminderen. Het is bijvoorbeeld beter om de formule “x 2 -y 2” te berekenen met behulp van de formule “(x-y)(x+y)”.
4.2 Niet-associativiteit van rekenkundige bewerkingen
Bij drijvende-kommaberekeningen geldt de regel (a*b)*c = a*(b*c) niet voor rekenkundige bewerkingen. Bijvoorbeeld,

(10 20 +1)-10 20 =0 ≠ (10 20 -10 20)+1=1

Laten we zeggen dat we een programma hebben voor het optellen van getallen.

Dubbele s = 0,0; voor (int i=0; ik Sommige compilers herschrijven de code mogelijk standaard om meerdere ALU's tegelijkertijd te gebruiken (ervan uitgaande dat n deelbaar is door 2):

Dubbele sa, s; sa=sa=0,0; voor (int i=0; ik Omdat sombewerkingen niet associatief zijn, kunnen de twee programma's verschillende resultaten opleveren.

4.3 Numerieke constanten
Houd er rekening mee dat niet alle decimale getallen een binaire drijvende-kommaweergave hebben. Het getal "0,2" zou bijvoorbeeld met enkele precisie worden weergegeven als "0,200000003". Dienovereenkomstig: “0,2 + 0,2 ≈ 0,4.” Absolute fout in het individu
In dit geval is deze misschien niet hoog, maar als we zo'n constante in een lus gebruiken, kunnen we de geaccumuleerde fout verkrijgen.
4.4 Het minimum van twee waarden selecteren
Laten we zeggen dat we het minimum van twee waarden moeten kiezen. In C kan dit op een van de volgende manieren worden gedaan:
  1. X< y? x: y
  2. X<= y? x: y
  3. x > y? y: x
  4. x >= y? y:x
Vaak beschouwt de compiler ze als gelijkwaardig en gebruikt hij altijd de eerste optie, omdat deze in één processorinstructie wordt uitgevoerd. Maar als we rekening houden met ±0 en NaN, zijn deze bewerkingen op geen enkele manier gelijkwaardig:
X j X< y? x: y X<= y? x: y x > y? y:x x >= y? y:x
+0 -0 -0 +0 +0 -0
NaN 1 1 1 NaN NaN
4.5 Vergelijking van cijfers
Een veel voorkomende fout bij het werken met floats doet zich voor bij het controleren op gelijkheid. Bijvoorbeeld,

Zwevende f-waarde = 0,2; als (fWaarde == 0,2) DoStuff();
De fout hier is ten eerste dat 0,2 geen exacte binaire representatie heeft, en ten tweede dat 0,2 een constante met dubbele precisie is, en dat de variabele fValue enkelvoudig is, en er is geen garantie over het gedrag van deze vergelijking.

De beste, maar nog steeds foutieve, manier is om het verschil te vergelijken met de toegestane absolute fout:

Als (fabs(fWaarde – fVerwacht)< 0.0001) DoStuff(); // fValue=fExpected?

Het nadeel van deze benadering is dat de fout bij het weergeven van een getal toeneemt naarmate het getal zelf toeneemt. Dus als het programma "10000" verwacht, dan geldt de bovenstaande gelijkheid niet voor het dichtstbijzijnde aangrenzende nummer (10000,000977). Dit geldt vooral als het programma een conversie van enkele naar dubbele precisie bevat.

Het kiezen van de juiste vergelijkingsprocedure is moeilijk en ik verwijs geïnteresseerde lezers naar het artikel van Bruce Dawson. Het stelt voor om getallen met drijvende komma te vergelijken door ze om te zetten in een integer-variabele. Dit is de beste, hoewel niet draagbare, manier:

Bool AlmostEqual2sComplement(float A, float B, int maxUlps) ( // maxUlps mag niet negatief zijn en niet te groot, zodat // NaN niet gelijk is aan een getal assert(maxUlps > 0 && maxUlps< 4 * 1024 * 1024); int aInt = *(int*)&A; // Уберем знак в aInt, если есть, чтобы получить правильно упорядоченную последовательность if (aInt < 0) aInt = 0x80000000 - aInt; //aInt &= 0x7fffffff; //(см. комментарий пользователя Vayun) // Аналогично для bInt int bInt = *(int*)&B; if (bInt < 0) bInt = 0x80000000 - bInt; /*aInt &= 0x7fffffff;*/ unsigned int intDiff = abs(aInt - bInt); /*(см. комментарий пользователя Vayun)*/ if (intDiff <= maxUlps) return true; return false; }

In dit programma is maxUlps (van Units-In-Last-Place) het maximale aantal drijvende-kommagetallen dat tussen de geteste waarde en de verwachte waarde kan liggen. Een andere betekenis van deze variabele is het aantal binaire cijfers (beginnend met de minst significante) in de vergeleken getallen die mogen worden weggelaten. MaxUlps=16 betekent bijvoorbeeld dat de onderste 4 bits (log 2 16) mogelijk niet overeenkomen, maar dat de getallen nog steeds als gelijk worden beschouwd. In dit geval zal de absolute fout, vergeleken met het getal 10.000, gelijk zijn aan 0,0146, en vergeleken met 0,001 zal de fout kleiner zijn dan 0,00000001 (10 -8).

5. Controleren van de volledigheid van IEE754-ondersteuning

Denkt u dat als processors volledig voldoen aan de IEEE754-standaard, elk programma dat standaard gegevenstypen gebruikt (zoals float/double in C) hetzelfde resultaat zal opleveren op verschillende computers? Je hebt het mis. Overdraagbaarheid en naleving van de standaard worden beïnvloed door de compiler- en optimalisatieopties. William Kahan schreef een programma in C (er is ook een versie voor Fortran) waarmee je kunt controleren of de combinatie “architectuur + compiler + opties” voldoet aan IEEE754. Het heet “Floating point paranoia” en de bronteksten ervan kunnen worden gedownload. Een soortgelijk programma is beschikbaar voor GPU's. De Intel Compiler (icc) gebruikt bijvoorbeeld standaard het ‘relaxte’ IEEE754-model, waardoor niet alle tests worden uitgevoerd. Met de optie "-fp-model exact" kunt u het programma exact volgens de standaard compileren. De GCC-compiler heeft een "-ffast-math"-optie die ervoor zorgt dat IEEE754 niet wordt nageleefd.

Conclusie

Eindelijk een leerzaam verhaal. Toen ik aan een testproject op de GPU werkte, had ik een seriële en parallelle versie van hetzelfde programma. Nadat ik de uitvoeringstijd had vergeleken, was ik erg blij omdat ik een versnelling van 300x kreeg. Maar later bleek dat de berekeningen op de GPU "uit elkaar vielen" en zich tot NaN wendden, en het werken ermee in de GPU ging sneller dan met gewone cijfers. Een ander ding was interessant: hetzelfde programma op de GPU-emulator (op de CPU) leverde het juiste resultaat op, maar op de GPU zelf niet. Later bleek dat het probleem was dat deze GPU de IEEE754-standaard niet volledig ondersteunde en de directe aanpak niet werkte.

Zwevende-kommaberekeningen zijn nu bijna perfect. Bijna altijd zal een naïeve aanpak werken, en een programma dat geen rekening houdt met al zijn functies zal het juiste resultaat opleveren, en de beschreven valkuilen hebben alleen betrekking op exotische gevallen. Maar je moet altijd waakzaam blijven: in een kwestie als computerwiskunde is het gemakkelijk om op de hark te trappen.
!

Tags toevoegen

Getallen weergeven in een computer Gehele getallen zijn de eenvoudigste numerieke gegevens waarmee een computer werkt. Gehele getallen worden opgeslagen op een computer in vast puntformaat

Om een ​​niet-negatief geheel getal op te slaan, wordt één geheugencel van 1 byte (8 bits) toegewezen, dat wil zeggen dat het bereik van getallen dat in het RAM-geheugen kan worden opgeslagen in het formaat van niet-negatieve gehele getallen is van 0 tot 255 (256 in totaal). Het minimale getal 0 komt overeen met acht nullen, en het maximale aantal 255 komt overeen met acht enen (255 10 = 11111111 2).

Om een ​​geheel getal met teken weer te geven, wordt het meest significante (linker) bit toegewezen aan het teken van het getal, de overige bits worden toegewezen aan het getal zelf. Als het getal positief is, wordt 0 in het tekenbit geplaatst, als het negatief is - 1. Tekengetallen van -128 tot 127 kunnen bijvoorbeeld in een byte worden weergegeven.

De computerweergave van gehele getallen gebruikt doorgaans één, twee of vier bytes, wat betekent dat de geheugencel respectievelijk acht, zestien of tweeëndertig bits lang zal zijn.

De weergave van een getal in de gebruikelijke vorm "teken" - "grootte", waarbij het meest significante cijfer van de cel wordt toegewezen aan het teken, en de rest - voor het schrijven van het getal in het binaire systeem, wordt genoemd directe code van een binair getal.

De directe code van de binaire getallen 1001 en -1001 voor een 8-bits cel is bijvoorbeeld respectievelijk 0 0001001 en 1 0001001.

Positieve getallen worden op een computer altijd weergegeven met behulp van directe code. De directe code van het nummer valt volledig samen met de opname van het nummer zelf in de cel van de machine.

De directe code van een negatief getal verschilt alleen van de directe code van het overeenkomstige positieve getal in de inhoud van het tekenbit.
Maar negatieve gehele getallen worden niet weergegeven in een computer met behulp van directe code; extra code.

De twee-complementcode van een positief getal is gelijk aan de directe code van dat getal.

De twee-complementcode van een negatief getal m is 2 n -|m|, waarbij n het aantal cijfers in de cel is.

Complementaire code wordt gebruikt om rekenkundige bewerkingen eenvoudiger uit te voeren. Als een computer zou werken met directe codes van positieve en negatieve getallen, dan zouden bij het uitvoeren van rekenkundige bewerkingen een aantal extra handelingen moeten worden uitgevoerd. Bij het optellen zou men bijvoorbeeld de tekens van beide operanden moeten controleren en het teken van het resultaat moeten bepalen. Als de tekens hetzelfde zijn, wordt de som van de operanden berekend en wordt hetzelfde teken toegewezen. Als de tekens verschillend zijn, wordt het kleinere getal in absolute waarde afgetrokken van het grotere getal en wordt aan het resultaat het teken van het grotere getal toegekend. Dat wil zeggen, met een dergelijke weergave van getallen (in de vorm van alleen directe code), wordt de optelbewerking geïmplementeerd via een tamelijk complex algoritme. Als negatieve getallen worden weergegeven in de vorm van een extra code, wordt de optelling, inclusief die van verschillende tekens, beperkt tot hun bitsgewijze optelling.

Algoritme voor het verkrijgen van de complementaire code van een negatief getal.

Om een ​​extra k-bitcode van een negatief getal te verkrijgen, moet u:

    de module van een negatief getal wordt weergegeven door directe code in k-binaire cijfers;

    keer de waarde van alle bits om: vervang alle nullen door enen, en enen door nullen, er wordt dus een k-bit omgekeerde code van het originele getal verkregen);

    voeg er één toe aan de resulterende omgekeerde code.

Voorbeeld:

We krijgen de 8-bit complementcode voor het getal -52:
00110100 - nummer |-52|=52 in directe code
11001011 - nummer -52 in omgekeerde code
11001100 - aantal -52 V extra code

Weergave van reële getallen in een computer.

Om reële getallen in moderne computers weer te geven, is een methode aangenomen drijvende-kommaweergaven.

Deze representatiemethode is gebaseerd op de genormaliseerde (exponentiële) notatie van reële getallen.
Een genormaliseerde notatie voor een reëel getal A dat niet nul is, is een notatie van de vorm:
A= m* q n ,
Waar
m is de mantisse van het getal (een echte breuk waarin het eerste cijfer na de komma niet gelijk is aan nul),
q is de basis van het systeem,
n - nummervolgorde.

Voorbeelden:
1. 3,1415926 = 0, 31415926 * 101;
2. 1000=0,1 * 104;
3. 0,123456789 = 0,123456789 * 100;
4. 0,00001078 = 0,1078 * 8-4; (de bestelling is geschreven in het 10e systeem)
5. 1000,00012 = 0, 100000012 * 24.

Bij het weergeven van getallen met drijvende komma wordt een deel van de cijfers van de cel toegewezen om de volgorde van het getal vast te leggen, de overige cijfers worden toegewezen om de mantisse vast te leggen. Eén cijfer in elke groep wordt toegewezen om het orderteken en het mantisseteken weer te geven.

    Gehele getallen zijn de eenvoudigste numerieke gegevens waarmee een computer werkt. Er zijn twee representaties voor gehele getallen: niet-ondertekend (alleen voor niet-negatieve gehele getallen) en ondertekend. Het is duidelijk dat negatieve getallen alleen in ondertekende vorm kunnen worden weergegeven. Gehele getallen in een computer worden opgeslagen in vast puntformaat.

  • Weergave van gehele getallen in typen gehele getallen zonder teken.

    Voor een representatie zonder teken worden alle bits van de cel toegewezen om het getal zelf weer te geven. Een byte (8 bits) kan bijvoorbeeld niet-ondertekende getallen van 0 tot 255 vertegenwoordigen. Als dus bekend is dat een numerieke waarde niet-negatief is, is het winstgevender om deze als niet-ondertekend te behandelen.

    Weergave van gehele getallen in integer-typen met teken. Voor representatie met teken wordt het meest significante (linker) bit toegewezen aan het teken van het getal, de overige bits worden toegewezen aan het getal zelf. Als het getal positief is, wordt 0 in het tekenbit geplaatst, als het negatief is - 1. Tekengetallen van -128 tot 127 kunnen bijvoorbeeld in een byte worden weergegeven.

    Directe nummercode. De weergave van een getal in de gebruikelijke vorm "teken" - "grootte", waarbij het meest significante cijfer van de cel wordt toegewezen aan het teken, en de rest - voor het schrijven van het getal in het binaire systeem, wordt genoemd directe code binair getal. De directe code van de binaire getallen 1001 en -1001 voor een 8-bits cel is bijvoorbeeld respectievelijk 00001001 en 10001001. Positieve getallen worden op een computer altijd weergegeven met behulp van directe code. De directe code van het nummer valt volledig samen met de opname van het nummer zelf in de cel van de machine. De directe code van een negatief getal verschilt alleen van de directe code van het overeenkomstige positieve getal in de inhoud van het tekenbit. Maar negatieve gehele getallen worden niet weergegeven in een computer met behulp van zogenaamde directe code; extra code. Aanvullende code positief getal is gelijk aan de directe code van dit getal. De twee-complementcode van een negatief getal m is 2 k -|m|, waarbij k het aantal cijfers in de cel is. Zoals eerder vermeld, worden bij het weergeven van niet-negatieve getallen in een niet-ondertekend formaat alle cijfers van de cel toegewezen aan het getal zelf. Als u bijvoorbeeld het getal 243=11110011 in één byte schrijft met een niet-ondertekende weergave, ziet dit er als volgt uit:

Bij het weergeven van gehele getallen met teken wordt het meest significante (linker) cijfer toegewezen aan het teken van het getal, en blijft er één cijfer minder over voor het getal zelf. Als de bovenstaande celstatus wordt beschouwd als een record van een geheel getal met teken, wordt voor de computer het getal -13 (243+13=256=28) in deze cel geschreven. Maar als ditzelfde negatieve getal in een cel van 16 cijfers wordt geschreven, is de inhoud van de cel als volgt:

    Teken cijfer De vraag rijst: voor welk doel worden negatieve getallen geschreven in de vorm van een extra code en hoe kun je de aanvullende code van een negatief getal verkrijgen? Er wordt gebruik gemaakt van een aanvullende code om rekenkundige bewerkingen te vereenvoudigen. Als een computer zou werken met directe codes van positieve en negatieve getallen, dan zouden bij het uitvoeren van rekenkundige bewerkingen een aantal extra handelingen moeten worden uitgevoerd.

    Bij het optellen zou men bijvoorbeeld de tekens van beide operanden moeten controleren en het teken van het resultaat moeten bepalen. Als de tekens hetzelfde zijn, wordt de som van de operanden berekend en wordt hetzelfde teken toegewezen. Als de tekens verschillend zijn, wordt het kleinere getal in absolute waarde afgetrokken van het grotere getal en wordt aan het resultaat het teken van het grotere getal toegekend. Dat wil zeggen, met deze weergave van getallen (in de vorm van alleen directe code) wordt de optelbewerking geïmplementeerd via een tamelijk complex algoritme. Als negatieve getallen worden weergegeven in de vorm van een complementaire code, wordt de optelling, inclusief die van verschillende tekens, gereduceerd tot bitsgewijze optelling. De computerweergave van gehele getallen gebruikt doorgaans één, twee of vier bytes, wat betekent dat de geheugencel respectievelijk acht, zestien of tweeëndertig bits lang zal zijn. Algoritme voor het verkrijgen van de complementaire code van een negatief getal.

    Om een ​​extra k-bitcode van een negatief getal te verkrijgen, moet u:

    de module van een negatief getal wordt weergegeven door directe code in k binaire cijfers;

    keer de waarde van alle bits om: vervang alle nullen door enen, en enen door nullen (zo wordt een k-bit omgekeerde code van het originele getal verkregen); voeg er één toe aan de resulterende omgekeerde code. Voorbeeld:

    We krijgen de 8-bit complementcode voor het getal -52:

    00110100 - nummer |-52|=52 in directe code

    11001011 - nummer -52 in omgekeerde code

    11001100 - het getal -52 in twee-complement Het zal je misschien opvallen dat de weergave van een geheel getal niet erg handig is om weer te geven in het binaire systeem, daarom wordt vaak de hexadecimale weergave gebruikt:

    Om reële getallen in moderne computers weer te geven, is de representatiemethode aangenomen drijvende punt.

  • Deze representatiemethode is gebaseerd op de genormaliseerde (exponentiële) notatie van reële getallen. Net als bij gehele getallen wordt bij het weergeven van reële getallen op een computer het binaire systeem het vaakst gebruikt. Daarom moet het decimale getal eerst worden geconverteerd naar het binaire systeem. Weergave van getallen met drijvende komma. Bij het weergeven van getallen met drijvende komma wordt een deel van de cijfers van de cel toegewezen om de volgorde van het getal vast te leggen, de overige cijfers worden toegewezen om de mantisse vast te leggen. Eén cijfer in elke groep wordt toegewezen om het orderteken en het mantisseteken weer te geven. Om geen teken van orde op te slaan, de zogenaamde verschoven volgorde , die wordt berekend met de formule 2 a-1 + IP, waarbij a het aantal cijfers is dat aan de bestelling is toegewezen. Voorbeeld

    : Als de ware volgorde -5 is, dan is de vertekende volgorde voor een getal van 4 bytes 127-5=122.

    Algoritme voor het weergeven van een getal met drijvende komma.

    Converteer een getal van het p-ary getalsysteem naar binair;

    vertegenwoordigen een binair getal in genormaliseerde exponentiële vorm;

    plaats het teken, de volgorde en de mantisse in de juiste rastercijfers.

    Voorbeeld: Geef het getal -25.625 weer in machinevorm met behulp van een representatie van 4 bytes (waarbij 1 bit wordt toegewezen voor het teken van het getal, 8 bits voor de verschoven volgorde, de resterende bits voor de mantisse).

  • 25 10 =100011 2 0,625 10 =0,101 2 -25,625 10 = -100011,101 2 2. -100011,101 2 = -1,00011101 2 * 2 4 3. SP=127+4=131 4.

  • Het zal je misschien opvallen dat de weergave van een reëel getal niet erg handig is om in binair getal weer te geven, daarom wordt vaak hexadecimale weergave gebruikt:

  • Eindantwoord: C1CD0000.

  • Schrijf de interne representatie van het getal 250.1875 in drijvende-kommavorm.

  • 1) Laten we het omzetten naar het binaire getalsysteem met 24 significante cijfers: 250,1875 10 =1111 1010, 0011 0000 0000 0000 2. 2) Schrijf het in de vorm van een genormaliseerd binair getal met drijvende komma: 0,1111 1010 0011 0000 0000 0000*10 2 1000 .

  • Hier worden de mantisse, radix (2 10 =10 2) en exponent (8 10 =1000 2) binair geschreven. 3) Bereken de machinevolgorde in het binaire getalsysteem: Mp 2 = 1000 + 100 0000 = 100 1000. 4) Schrijf de representatie van het getal in een geheugencel van 4 bytes, rekening houdend met het teken van het getal: Hexadecimale vorm: 48FA3000. in het bereik van 0000000 tot 1111111. Dit betekent dat de machinevolgorde varieert in het bereik van 0 tot 127 (in het decimale getalsysteem). Er zijn in totaal 128 waarden.

    De volgorde kan uiteraard zowel positief als negatief zijn.

    Het is redelijk om deze 128 waarden gelijk te verdelen tussen positieve en negatieve ordewaarden: van -64 tot 63.

    De machinevolgorde is verschoven ten opzichte van de wiskundige volgorde en heeft alleen positieve waarden.

De offset wordt zo gekozen dat de minimale wiskundige ordewaarde overeenkomt met nul.

Het verband tussen de machinevolgorde (Mp) en de wiskundige orde (p) wordt in het onderhavige geval uitgedrukt door de formule: Mp = p + 64 De resulterende formule wordt geschreven in het decimale systeem.

In het binaire systeem heeft de formule de vorm: Mp 2 =p 2 +1000000 2 Om de interne representatie van een reëel getal in een cel van 4 bytes vast te leggen, moet je: 1) de modulus van dit getal omzetten naar het binaire getal systeem met 24 significante cijfers; 2) normaliseer het binaire getal; 3) vind de machinevolgorde in het binaire getalsysteem; 4) Houd rekening met het teken van het getal en noteer de weergave ervan in een machinewoord van 4 bytes.

Algemene informatie. Gegevenstype is een binaire code die bekende eigenschappen heeft volgens geaccepteerde conventies. De processor herkent (met behulp van opdrachten) het gegevenstype en voert een voorgeschreven reeks bewerkingen op de gegevens uit.

De volgende gegevenstypen worden hieronder besproken:● s

ondertekende en niet-ondertekende gehele getallen, gebruikt om gehele getallen weer te geven in de vorm van binaire codes en er rekenkundige bewerkingen op uit te voeren volgens de regels van de binaire rekenkunde;

BCD gehele getallen, ontworpen om decimale getallen weer te geven en te verwerken;

Booleaans gegevenstype

Houd er rekening mee dat er in programma's die in talen op hoog niveau zijn geschreven, gegevenstypen kunnen voorkomen waarvoor de processor geen hardware levert. Een voorbeeld hiervan zijn gegevenstypen met drijvende komma in een Fort Run-programma dat op een computersysteem zonder coprocessor draait. In dit geval gebruiken de berekeningen aanvullende opdrachten om gegevenstypen met drijvende komma te modelleren. Als er een co-processor in het systeem zit (en een Fortran-compiler daarvoor), zal het programma uiteraard veel sneller worden uitgevoerd.

Over de vormen van het weergeven van getallen.

Er worden veel twee vormen gebruikt om getallen weer te geven: natuurlijk en normaal.

Bij natuurlijk in de vorm van representatie heeft het nummer één type opname, bijvoorbeeld: +195 - positief geheel getal; –195 is een negatief geheel getal; +0,025 - juiste positieve fractie; –195,025 is een onechte negatieve breuk. Dit formulier wordt gebruikt om gehele getallen en komma-getallen weer te geven.

Bij normaal representatieformulier, het nummer wordt in het formulier geschreven

waarbij M, P de mantisse en de volgorde van het getal zijn.

De normale weergavevorm wordt gekenmerkt door een dubbelzinnige notatie van het getal, bijvoorbeeld: +195,025 = +195025. 10 –3 = +19,5025. 10 1 = +0,195025 . 10 3. Zoals uit het voorbeeld blijkt, hangt de positie van het mantissepunt af van de waarde van de orde P. Bij een verandering in P (wat altijd gebeurt tijdens het berekeningsproces) lijkt het punt te gaan zweven. Daarom wordt de normale vorm (2.3.1) ook wel de vorm van weergave van drijvende-kommagetallen genoemd.

Numerieke (net als alle andere) informatie die onderworpen is aan verwerking door de processor, wordt weergegeven in het formulier

– bit binaire codes, voor het opslaan van welke geheugencellen worden gebruikt. Binaire getalcodes hebben verschillende formaten.

Het getalformaat is een verzameling bits (bitraster), verdeeld in afzonderlijke velden: het hekjeveld, het getalmodulusveld, het mantisseveld, het ordemodulusveld, enz. Om de bits van de velden te nummeren, wordt een reeks van Er wordt gebruik gemaakt van getallen, beginnend bij nul (0, 1, 2, 3, …).

Niet-ondertekende gehele getallen.

Dit gegevenstype wordt gebruikt om nul- en positieve gehele waarden weer te geven.

In afb. 2.3.1, en de formaten van 8-bit gehele getallen worden gegeven. Er is geen tekenbit, dus het bereik van getallen is 0…2

De bitdiepte van de binaire code is hetzelfde als de bitbreedte van het getal.

Getekende gehele getallen.

De bewerking van het aftrekken van twee positieve getallen A en B kan worden beschouwd als een bewerking van het algebraïsch optellen van getallen met verschillende tekens: A – B = A + (–

). Om de rekenkundige bewerking van het aftrekken te vervangen door de bewerking van algebraïsche optelling, is het daarom noodzakelijk om op de een of andere manier het teken van het getal weer te geven. Normaal gesproken wordt een extra bit toegewezen voor het teken van een binair getal. Het teken van het getal wordt aangegeven in het meest significante cijfer: 0 komt overeen met het positieve teken “+” van het getal, 1 - met het negatieve teken “–”.

Om ondertekende nummers weer te geven, wordt het veel gebruikt aanvullend code.

Om gehele getallen weer te geven positief binaire getallen in

– in de complementcode van de bit moeten alle meest significante bits (inclusief de tekenbit) gevuld zijn met nullen.

Voor presentatie negatief nummers nodig:

● alle significante digitale cijfers (modulus) van een getal omkeren;

● voeg één toe aan de resulterende waarde;

● vul alle belangrijkste cijfers (inclusief de tekencijfers) met enen.

De 8-bits twee-complementcode voor een positief getal +6 is bijvoorbeeld 00000110, voor een negatief getal - 6 - 11111010.

In afb. 2.3.1, b toont de formaten van 8-bits getallen met teken in twee-complementcode. Het bereik van hun weergave is – 2 (

–1) - cijfercapaciteit van het significante deel van het nummer. Moderne microprocessors ondersteunen gehele getallen met teken van 16, 32 en 64 bits. Er zijn twee veelgebruikte gehele formaten: kort met het aantal cijfers

En lang met het aantal cijfers 2

Bij het berekeningsproces wordt het lange formaat gebruikt, de resultaten worden in het korte formaat weergegeven. Als het aantal significante cijfers van de modulus van een getal groter is dan (

– 1), loopt het bitraster over, wat leidt tot een fout in de weergave van het getal als gevolg van het verlies van de belangrijkste bits van de module. Na het uitvoeren van rekenkundige bewerkingen wordt het resultaat dat buiten het bereik valt gemarkeerd door de overloopvlag O op één te zetten

Vaste puntnummers.

In de natuurlijke vorm van het weergeven van reële getallen wordt de positie van het punt (komma) vastgelegd tussen de gehele en gebroken delen van het getal. Om de positie van een punt in een reëel getal te veranderen, is het noodzakelijk een schaalfactor te introduceren, waarvan de waarde zo moet worden gekozen dat de waarde van het reële getal ongewijzigd blijft. Vaak wordt het punt vóór de meest significante cijfers van de modulus van het getal vastgesteld. In dit geval heeft de weergave van het getal A met een vast punt de vorm van een echte breuk, die overeenkomt met de voorwaarde

Het geselecteerde aantal significante cijfers van een getal.

Voor de initiële gegevens van het probleem en alle tussenresultaten van berekeningen moet aan voorwaarde (2.3.2) worden voldaan, wat wordt verzekerd door de schaalfactor K te kiezen.

Als voorwaarde (2.3.2) wordt geschonden, heeft het getal А Ф een geheel getal, dat verloren gaat omdat het door overflow niet in het bitraster valt. Daarom moet men bij het bepalen van de schaalfactor K uitgaan van de maximale waarde van de module van de getallen die betrokken zijn bij het oplossen van het probleem, waarbij K> | Een |

Dan is voldaan aan voorwaarde (2.3.2) voor А Ф = А/К.

In afb. 2.3.2, en het formaat van de computerweergave van getallen AF met een vast punt wordt gegeven. Wanneer het getal AF in een geheugencel wordt ingevoerd, worden de vrije cijfers van lage orde van het bitraster gevuld met nullen. Als het nummer

significante cijfers van de module |

– 1, dan de bits van lage orde van de module die er niet in passen

– bitraster, gaan verloren. Dit leidt tot een fout waarvan de absolute waarde kleiner is dan één van de minst significante cijfers van het bitraster, d.w.z.

32 absolute fout

0,5×10 – 30x0,3 = 0,5×10 – 9

Geef twee getallen A = –1010.101 2 en B = +10.10101 2, waarvoor |

Daarom is de schaalfactor K > |

2 4 = 10000 2. Macht 4 geeft aan dat de oorspronkelijke getallen 4 cijfers naar rechts moeten worden verschoven

Echt

A.K= –1010,101. 10000 =

–0.1010101 2 ;

VF = V. K = 10,10101. 10000 = 0,001010101 2 . De formaten voor het weergeven van getallen А Ф en В Ф worden getoond in Fig. 2.3.2.6, c. Om de nauwkeurigheid van de computerweergave van het getal VF te behouden, is het noodzakelijk om het bitraster uit te breiden naar 10 bits.

Het voordeel van het weergeven van getallen in de vorm van een vast punt is het gemak van het uitvoeren van rekenkundige bewerkingen. De nadelen zijn dat:

● het is noodzakelijk om schaalfactoren te selecteren;

● nullen in de meest significante bits van de module leiden tot een afname van het aantal bits dat wordt ingenomen door het significante deel van de module van het nummer. Als gevolg hiervan neemt de nauwkeurigheid van het weergeven van getallen met kleine moduluswaarden af.

Booleaanse typen.

Booleaanse waarden zijn niet ondertekend en worden gebruikt in logische bewerkingen

etc. De bewerking wordt uitgevoerd op individuele bits. Booleaanse operanden worden in delen verwerkt als hun bitcapaciteit groter is dan de bitcapaciteit van de processor.

Binaire decimale gehele getallen.

IN het dagelijks leven mensen gebruiken het decimale getalsysteem. Voor het opslaan en verwerken van decimale getallen in digitale apparaten ze worden weergegeven als binaire code. Prestatie decimaal getal, waarin elk decimaal cijfer wordt weergegeven als binaire symbolen 0 en 1, wordt BCD genoemd. Omdat het decimale systeemalfabet uit 10 cijfers bestaat, wordt elk decimaalcijfer geschreven in een woord dat ten minste vier cijfers bevat. Het meest gebruikte woord is een 4-bits woord dat een tetrad of knabbel wordt genoemd. Door tetrads te gebruiken, in plaats van de vereiste 10, kun je 2 4 = 16 verschillende combinaties van gecombineerde symbolen 0 en 1 krijgen. Bij binaire decimale codering moeten verschillende decimale cijfers overeenkomen diverse combinaties symbolen O en 1, d.w.z. slechts 10 van de 16 combinaties zijn toegestaan. De aanwezigheid van toegestane en verboden combinaties is een belangrijke eigenschap van binaire decimale codes. Deze eigenschap onderscheidt ze van gewoon positioneringssystemen Getallen waarin alle combinaties zijn toegestaan. Het totaal aantal verschillende toegestane 4-bits codes (tetrads), bepaald door combinaties van 16 elementen van 10, is: C 10 16 = 18008. De zogenaamde code 8421, die gebruik maakt van de eerste tien waarden van binaire getallen uit 0000 (0 10), wordt veel gebruikt tot 1001 (9 10).

Het voordeel van 4-cijferige codes is dat er bij het coderen van decimale getallen gebruik van wordt gemaakt minimale hoeveelheid ontladingen. Door de introductie van een extra 5e cijfer kunt u fouten tijdens de verzending detecteren numerieke informatie via communicatielijnen in aanwezigheid van interferentie. In een 5-bits code 2 uit 5 bevatten alle codecombinaties bijvoorbeeld twee enen en drie nullen. Daarom zal het wijzigen van een cijfer (naar de tegenovergestelde waarde) leiden tot een verboden codecombinatie.

In afb. 2.3.3 toont het formaat van een binair decimaal getal dat 18 tetrads bevat (

0) en tekenbit

(de resterende bits van de hoge byte worden op nulwaarden ingesteld). Elke tetrad komt overeen met één decimaal.

Drijvende-kommagetallen.

Voor het uitvoeren van berekeningen is het in veel gevallen noodzakelijk om cijfers te presenteren hoge nauwkeurigheid in een breed scala aan waarden. Voldoet aan de gestelde eisen normale vorm cijfers (2.3.1). Om de kenmerken van het gebruik ervan voor het weergeven van drijvende-kommagetallen in te identificeren digitale systemen we gaan ervan uit dat:

● om de mantisse te schrijven, (

1) – bit binaire code, met de hoogste orde (

Het –de) cijfer bepaalt het teken van de mantisse (getal), de overige cijfers bepalen de modulus van de mantisse. De waarde van de modulus van de mantisse |M|< 1, что соот-ветствует фиксации точки перед значащими цифрами (разрядами) модуля мантиссы;

● om de volgorde P vast te leggen, wordt (p + 1)-bit binaire code gebruikt, waarbij het meest significante (p-de) cijfer het teken van de volgorde bepaalt, terwijl de overige cijfers de modulus van de volgorde bepalen. De volgorde P (geheel getal) geeft de werkelijke positie van het punt in het getal aan.

In afb. 2.3.4, en het formaat van een drijvende-kommagetal wordt gegeven.

De nauwkeurigheid van de getalweergave (2.3.1) hangt af van het aantal significante cijfers (cijfers) van de mantisse. Om de nauwkeurigheid te vergroten, worden getallen met drijvende komma gepresenteerd in een genormaliseerde vorm, wat wordt aangegeven door de aanwezigheid aanzienlijk cijfer(eenheden voor

2) in het meest significante cijfer van de mantissemodule. De moduluswaarde van de genormaliseerde mantisse bij

2 ligt binnen 2 –1 ≤ |M|< 1 (для любых порядков П). В нормализованной форме могут быть представлены все числа из некоторого диапазона за исключением нуля.

Laten we de binaire getallen A = +10010,10101 en B = –111,0101 weergeven in drijvende-kommanotatie. Laten we A en B in genormaliseerde vorm schrijven

EEN = +0,1001010101 . 2 5 , V= –0,1110101000 . 2–3.

Gebaseerd op (2.3.4) schrijven we de modules van de mantisse |M

| = 1001010101 2 , |M

| = 1110101000 2 en bestel modules in het binaire systeem |P A | = 5 10 = 0101 2 , |P

| = 3 10 = 0011 2 . Selecteer het totale aantal cijfers van het bitraster

P = 16. We accepteren het aantal cijfers voor de mantissemodule als 10, voor de bestelmodule als 4.

De notaties van de getallen A en B worden getoond in Fig. 2.3.4, 6, c. De mantisse en de volgorde van operand B, die een negatieve waarde hebben, worden weergegeven in de twee-complementcode:

|# + 1 = 0001010111 + 1 = 0001011110;

|# + 1 = 0011 + 1 = 0100, waarbij # de inversie is.

Omdat de absolute fout bij het weergeven van getallen met drijvende komma afhangt van de orde van P, zullen we een schatting geven van de relatieve fout:

/ 2 –1 = 2 –(

Absolute fout in de weergave van de module

– beetje mantisse; |

22 –1 - minimale waarde genormaliseerde modulus van de mantisse.

Let er wel op in de standaard

754/854 gebruikt een volgorde in de vorm P = P – E, waarbij E =

Ordercompensatie; Pmax = 2E. Hierdoor konden we het veld uitsluiten

bestelteken in nummerweergaveformaat.