Hoe groot kan een 64-bits geheel getal zonder teken zijn?

Ik ben vrij duidelijk over Hoe groot kan een 64-bits geheel getal zijn ?
Dankzij deze vraag en de duidelijke antwoorden.

Dus, volgens dat, zou ik kunnen zeggen dat een unsigned int2^64 – 1 kan zijn in plaats van 2^63 – 1?

2^63 - 1:    0111111111111111111111111111111111111111111111111111111111111111
2^64 - 1:    1111111111111111111111111111111111111111111111111111111111111111

Als en alleen als ik het correct heb, hoe kan ik een niet-ondertekende overflow detecteren? Een overloop van een geheel getal met teken in de twee-complement-representatie zou de hoogste bitpositie binnenvallen en een negatief getal retourneren. Maar hoe zit het met deze niet-ondertekende zaak?


Antwoord 1, autoriteit 100%

Het is moeilijk of onmogelijk te detecteren door naar een waarde te kijken.
Het probleem is dat de maximale waarde plus zelfs maar 1 nog steeds een geldige waarde is; d.w.z. 0.

Dit is de reden waarom de meeste programmeurs zoveel mogelijk vermijden, als het eigenlijk een verkeerde waarde is. Voor sommige toepassingen is het omwikkelen onderdeel van de logica en prima.

Als u b.v. c=a+b;(a, b, c zijn 64-bits niet-ondertekende ints en a,b is zorgwekkend dicht bij max, of zou kunnen zijn) en willen weten of het resultaat wordt beïnvloed,

controleer vervolgens of ((max - b) < a); waarbij maxhet juiste door de compiler geleverde symbool is.

Bereken de maximale waarde niet zelf als 2^64-1, deze is implementatiespecifiek en platformspecifiek. Bovendien zal het de omhulling twee keer bevatten (2 ^ 64 is voorbij max, waarschijnlijk 0; en 1 aftrekken via 0 terug …). En dat geldt zelfs als ^wordt gezien als een passende versie van “to the power of”.


Antwoord 2, autoriteit 93%

Getekendgeheel getal kan alleen gaan tot 2^63-1(9.223.372.036.854.775.807) omdat het bit met de hoogste significantie is gereserveerd voor het teken. Als dit bit 1is, is het getal negatief en kan het zo laag als -2^63gaan (-9.223.372.036.854.775.808).

Op een 64-bits geheel getal met teken is 2^64-1eigenlijk het getal -1.

Als u echter gehele getallen zonder teken gebruikt, begint de waarde bij 0en wordt 2^64-1(18.446.744.073.709.551.615) de hoogste waarde, maar gehele getallen zonder teken kunnen geen negatieve waarden vertegenwoordigen .


Antwoord 3, autoriteit 56%

Uw aanname voor de maximale grootte van gehele getallen met en zonder teken is correct. De werkelijke waarden zijn 9223372036854775807 voor ondertekend en 18446744073709551615 voor niet-ondertekend.

Overflow detecteren voor niet-ondertekende toevoeging is vrij eenvoudig – als het resultaat minder is dan een van de operanden, was er een overflow.

Aftrekken is vergelijkbaar, als het resultaat groter is dan de eerste operand, was er sprake van overloop.

Vermenigvuldigen is moeilijk, ik ken daar geen eenvoudige regel voor.

Overloop is onmogelijk voor delen, tenzij je deelt door nul.


Antwoord 4, autoriteit 56%

Het kan 18446744073709551615zijn.

18,446,744,073,709,551,615
q5 q4  t   b   m   t   h

Antwoord 5, autoriteit 22%

Hoe groot kan een 64-bits geheel getal zonder teken zijn?

Als u het maximum wilt coderen, kunt u het beste UINT64_MAXgebruiken. Het wordt altijd gedefinieerd wanneer het 64-bits type beschikbaar is.

#include <stdint.h>
#define MAX64BIT UINT64_MAX 
or 
#define MAX64BIT 0xFFFFFFFFFFFFFFFF
or
#define MAX64BIT 18446744073709551615u

hoe kan ik een niet-ondertekende overflow detecteren?

Met N-bit niet-ondertekendetypen: uintN_t a,b;

Overloopdetectie:

// addition
uintN_t sum = a + b;
bool overflow = sum < a;  // or sum < b
// subtraction
bool overflow = b > a;
uintN_t diff = a - b;  //

Vanwege ongedefinieerd gedrag(UB) van ondertekende wiskunde, is andere code nodig met ondertekendetypen. Voorbeeld


Antwoord 6, autoriteit 22%

Hoe groot is 64 bit?

Het antwoord op de vraag hoe groot een niet-ondertekend 64-bits geheel getal is, zal ik voorstellen om een kleine vergelijkende test uit te voeren in assemblage of een programmeertaal die 64-bits gegevenstypen ondersteunt.

Tel van 0 tot de maximale waarde die in een variabele kan worden opgeslagen. Gebruik de eerste keer een 32-bits brede variabele en de tweede keer een 64-bits brede variabele. Probeer de resultaten te schatten.

In C# kan de code er als volgt uitzien voor een 32-bits variabele (… negeer alstublieft het uitschakelen met één probleem):

for (uint i = 0; i < uint.MaxValue; i++)
{
    Process(i);
}

uint.MaxValue is het getal dat je krijgt als je alle bits van de variabele op 1 zet. Het is in principe gelijk aan 2^32 – 1 = 4294967295. Dit is ongeveer 4,2 miljard.

De testcode voor de case met 64-bits variabele is vergelijkbaar:

for (ulong i = 0; i < ulong.MaxValue; i++)
{
    Process(i);
}

ulong.MaxValue is deze keer 2^64 – 1 = 18446744073709551615 (een getal van 20 cijfers).

Bij ongeveer 1 miljard Process() bewerkingen/seconde, zal het eerste programma zijn taak afmaken in:

2^32 / 1000000000 = 4,29 seconden

Bij dezelfde verwerkingssnelheid zal het tweede programma zijn taak afmaken in:

2^64 / 1000000000 / 3600 / 24 / 365 = 585 jaar!

Dat is nogal een verschil!!! Wie heeft de tijd om 585 jaar te wachten op een basis om zijn werk af te maken!

En het grappige is dat 1 miljard bewerkingen per seconde behoorlijk agressief is! Voor een realistischer scenario waarbij je 1 miljoen tot een paar honderd miljoen bewerkingen per seconde uitvoert, explodeert de tijd tot duizenden zelfs honderdduizenden jaren om er een te doen!!!

Voor de meeste mensen is de bovenstaande oefening een leuke visualisatie van 64-bits kracht. Maar deze oefening laat ook de realiteit zien waarmee informatici die met algoritmen werken, worden geconfronteerd. Een slecht geïmplementeerd algoritme (bijv. zoek- of rekenprobleem), dat een brute force-aanpak gebruikt, kan uw software heel goed verpesten.

Andere grote getallen

Houd er bij het samenvatten rekening mee dat het maximale aantal dat in een 64-bits register/variabele is opgeslagen 2^64 – 1 = 18446744073709551615 is (een getal van 20 cijfers). Hoe groot het ook lijkt, dit aantal is nog steeds klein in vergelijking met bijvoorbeeld 1 googol die 10^100 is (1 gevolgd door 100 nullen)!

En zelfs de grote googol is kleiner dan 70! (70 faculteit die 1 * 2 * … * 70) is. Wauw! Dit toont echt de kracht van vermenigvuldiging!

En u weet wat: de googol is goed binnen het bereik van het dubbele gegevenstype (IEEE 754 drijvend punt) – ook een 64-bits structuur. Hoe het dubbele beheert om dergelijke grote nummers op te slaan, zal in een toekomstig artikel worden gepresenteerd.

Ik hoop dat je plezier hebt gehad!

Other episodes