Naar de inhoud
HexSlate

Number Base Converter

Binair
0
Octaal
0
Decimaal
0
Hex
0
Gezette bits0/32
Bits nodig0
Two's complement bij 32 bits

0000 0000 0000 0000 0000 0000 0000 0000

Zonder teken
0
Met teken
0
Gezet op
geen
talstelsel 10 in0 bits breed0 bits gezet bij 32-bit

Waarom parseInt je laatste cijfers kwijtraakt

parseInt('deadbeefdeadbeef', 16) print 16045690984833335000. Het juiste antwoord is 16045690984833335023, en de waarde die echt wordt opgeslagen is 16045690984833335296, oftewel 273 te hoog. Er komt geen waarschuwing: er komt een getal terug, het ziet er qua grootte goed uit, en de laatste cijfers zijn verzonnen.

De oorzaak is het type, niet de parser. Een JavaScript Number is een float64, en die draagt 53 bits aan gehele precisie, dus elk heel getal boven 9.007.199.254.740.991 wordt afgerond op de dichtstbijzijnde waarde die het formaat kan vasthouden. Dat plafond ligt precies midden in het bereik waar mensen grondtallen voor omrekenen: een 64-bits hash, een Snowflake- of Twitter-id, een geheugenadres, een MAC-adres als één getal geschreven. Die zitten er allemaal boven.

Deze converter gebruikt BigInt voor elke waarde die hij aanraakt, in beide richtingen. Die heeft geen bovengrens, dus een sleutel van 512 bits gaat exact om, en de cijfers die je terugkrijgt zijn de cijfers die er stonden. Schrijf je de conversie zelf, dan is de oplossing dezelfde: BigInt('0x' + hex) voor de gangbare grondtallen, en een lus over de cijfers voor de rest, want BigInt() kent alleen decimaal en de drie vormen met voorvoegsel.

Two's complement, en waarom -1 gelijk is aan ffffffff

Een negatief getal heeft in een register geen minteken. Het heeft een bitpatroon, en de afspraak die elke huidige CPU gebruikt is two's complement: de bovenste bit is min zijn plaatswaarde waard in plaats van plus. In 8 bits is die bovenste bit dus -128 waard, en is 1111 1111 gelijk aan -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1, oftewel -1.

Het handige gevolg is dat optellen geen uitzondering nodig heeft. 255 + 1 loopt in een 8-bits register over naar 0, en -1 + 1 is ook 0, met dezelfde opteller en dezelfde carry. Het verklaart ook de scheefheid in elk signed bereik dat je ooit gezien hebt: 8 bits gaan van -128 tot 127, niet van -127 tot 127, omdat nul een van de positieve plekken inneemt.

De rijen Zonder teken en Met teken hierboven zijn twee lezingen van hetzelfde patroon. Niets in de bits zegt welke klopt. Het type in je code bepaalt dat, en een verwisseling van die twee is hoe een bestandsgrootte binnenkomt als 4.294.967.295 bytes of een temperatuur als 65.491 graden.

Voorvoegsels, en waar ze gelden

0x voor hex, 0b voor binair en 0o voor octaal zijn notatie uit broncode, geen deel van het getal. Plak er hier een met het bijbehorende grondtal geselecteerd en het wordt weggehaald. Plak 0xff met decimaal geselecteerd en de tool zegt dat, in plaats van te gokken, want juist die gok heeft twee aannemelijke antwoorden.

Er is één geval waarin een voorvoegsel geen voorvoegsel is. In grondtal 16 is 0b11 vier geldige hexcijfers ter waarde van 2.833. Het als binair lezen zou 3 opleveren, een factor 900 ernaast. Een voorvoegselletter telt daarom alleen als voorvoegsel in grondtallen waar hij niet ook een cijfer is, en daarom werkt 0x in decimaal en binair en betekent het iets anders in grondtal 36.

Pas ook op met de oudere octale vorm. Een losse nul vooraan, zoals in 0755, betekent octaal in C en in ouder JavaScript maar decimaal op de meeste andere plekken. Dat is dubbelzinnig genoeg dat deze tool het als een gewoon cijfer behandelt en het grondtal aan de keuzelijst overlaat.

Veelvoorkomende problemen

  • Nullen vooraan verdwijnen. Ze zijn niets waard, dus 00ff en ff zijn één getal. Waar de breedte ertoe doet, lees je hem af in het paneel met vaste breedte, dat aanvult tot het register dat je koos.
  • Een hash past niet in een integer. Een SHA-256 digest is 256 bits. Hier gaat hij exact om, maar geen enkele 64-bits kolom houdt hem vast, en hem door een Number afronden is de bug bovenaan deze pagina.
  • Grondtal 36 is geen grondtal 16 met meer letters in dezelfde volgorde. Het gebruikt 0 tot 9 en daarna a tot z, dus z is 35 en 10 is 36. Korte ids en URL-slugs zijn vaak grondtal 36 of 62, precies om die dichtheid.
  • Gezette bits tellen vanaf nul aan de rechterkant. Bit 0 is de plek van de enen. Rechtenvlaggen, feature masks en chmod-bits worden allemaal zo gelezen.

Veelgestelde vragen

Wat is het grootste getal dat dit aankan?

Er is geen plafond. De conversie draait op BigInt, dus een waarde van 200 cijfers gaat exact om, en het antwoord voorbij 2^53 klopt in plaats van dat het afgerond is. Dat is de hele reden dat deze pagina bestaat: de voor de hand liggende oplossing verliest stilletjes precisie lang voordat de cijfers op zijn.

Waarom houdt grondtal 36 daar op?

Omdat de symbolen op zijn. Grondtal 36 gebruikt de tien cijfers plus de zesentwintig letters, en er is geen zevenendertigste teken waar iedereen het over eens is. Grondtal 62 en 64 bestaan, maar die hebben een afgesproken alfabet nodig, en verschillende systemen kiezen een ander.

Hoe reken ik een negatief getal om?

Typ het met een minteken voor de gewone omrekening. Voor het bitpatroon dat een machine echt zou opslaan, gebruik je de weergave in two's complement en kies je de registerbreedte, want -1 is ffffffff in 32 bits en ffffffffffffffff in 64.

Kan het breuken omrekenen?

Nee, alleen hele getallen. Breuken tussen grondtallen omrekenen is een ander probleem met eigen afrondingsvallen, en een tool die dat half ondersteunt is slechter dan een die het gewoon zegt.

Er verlaat niets dit tabblad

De omrekening draait in je browser. De waarde die je typt gaat nergens heen en komt niet in de URL. Het grondtal en de registerbreedte wel, dus een link draagt je instellingen en niet je data. Heb je de bytes van een tekst nodig in plaats van de cijfers van een getal, dan is de converter van tekst naar binair daarvoor.