Talbaser, bytestorlekar och enheterna folk grälar om
Ett skrivet tal bär två saker: ett värde, och en uppsättning antaganden om hur det ska läsas. 0xFF, 255, 0o377 och 11111111 är en och samma kvantitet i fyra notationer. En terabyte och en tebibyte skiljer sig med tio procent. 1,234 är ungefär tusen i London och ungefär ett i Berlin. De flesta numeriska buggar kommer från antagandena snarare än från räknandet.
Binärt, oktalt, decimalt och hexadecimalt
Varje positionsbas fungerar likadant. Varje position är värd basen gånger positionen till höger om den, och siffrorna löper från noll till basen minus ett. Bas 16 behöver sex extra siffror, så den lånar A till F för tio till femton.
Hexadecimalt används för bytes och färger eftersom 16 är 2 upphöjt till 4, så en hexadecimal siffra är exakt fyra bitar och en byte är exakt två hexadecimala siffror, utan någon minnessiffra mellan dem.
0 0000 4 0100 8 1000 C 1100
1 0001 5 0101 9 1001 D 1101
2 0010 6 0110 A 1010 E 1110
3 0011 7 0111 B 1011 F 1111
Den tabellen är hela konverteringen. För att gå från hexadecimalt till binärt, ersätt varje siffra med sina fyra bitar: 0x2F blir 0010 1111. För att gå tillbaka, gruppera bitarna fyra och fyra från höger, fyll ut till vänster med nollor och läs av varje grupp i tabellen.
För decimalt, använd platsvärdena. 0x2F är 2 x 16 + 15, vilket är 47. Åt andra hållet dividerar du upprepade gånger med 16 och läser resterna nedifrån och upp:
200 / 16 = 12 remainder 8 -> 8
12 / 16 = 0 remainder 12 -> C
200 decimal = 0xC8
Oktalt packar tre bitar per siffra, vilket är varför Unix-rättigheter skrivs som 755: varje siffra är en rwx-trippel, där 7 är 111 och 5 är 101. En CSS-färg som #FF8800 är tre bytes, en per kanal, var och en löpande 0 till 255, och kortformen med tre siffror #F80 expanderar genom att varje siffra dubbleras snarare än genom utfyllnad med nollor. Number Base Converter täcker alla fyra baserna på en gång.
Tvåkomplement, och varifrån intervallen kommer
En byte rymmer 256 skilda mönster. Lästa utan tecken är de 0 till 255. Lästa med tecken markerar den översta biten den negativa halvan, och ett negativt värde är dess mönster minus 256. Det systemet är tvåkomplement, valt för att vanlig binär addition då fungerar identiskt på värden med och utan tecken.
För att negera ett tal, invertera varje bit och lägg till ett. Intervallet är asymmetriskt eftersom nollan upptar en av de 128 platserna i den icke-negativa halvan, så en byte med tecken löper från -128 till 127. Att lägga till ett till toppen av intervallet slår runt till botten:
0111 1111 127
+ 0000 0001 1
= 1000 0000 -128
I de flesta språk flaggas ingenting; värdet dyker helt enkelt upp på andra sidan av intervallet. Samma runtslag vid 32 bitar är 2038-problemet, där en Unix-tidsstämpel på 32 bitar med tecken tar slut vid 2 147 483 647 sekunder. 16 bitar utan tecken ger 0 till 65 535, vilket är precis därför TCP-portnummer slutar där, och varför Random Port Generator drar ur det intervallet samtidigt som den undviker de reserverade portarna under 1024.
Kilobyte, kibibyte och de saknade gigabyten
Lagringstillverkare räknar i tiopotenser. Operativsystem har historiskt räknat i tvåpotenser och märkt resultatet med decimalprefixet, vilket är där grälet börjar. De binära prefixen (KiB, MiB, GiB) finns för att undanröja tvetydigheten.
| Tiopotens | Decimalvärde | Binärt prefix | Binärt värde | Glapp |
|---|---|---|---|---|
| kB, 10^3 | 1 000 | KiB, 2^10 | 1 024 | 2,4 % |
| MB, 10^6 | 1 000 000 | MiB, 2^20 | 1 048 576 | 4,9 % |
| GB, 10^9 | 1 000 000 000 | GiB, 2^30 | 1 073 741 824 | 7,4 % |
| TB, 10^12 | 1 000 000 000 000 | TiB, 2^40 | 1 099 511 627 776 | 10,0 % |
| PB, 10^15 | 10^15 | PiB, 2^50 | 1 125 899 906 842 624 | 12,6 % |
En disk på 1 TB rymmer 10^12 bytes som såld. Dividera det med 2^30 så får du 931,32, så Windows rapporterar omkring 931 GB och använder decimaletiketten för en binär kvantitet. Ingenting saknas; samma bytes divideras med ett annat tal. macOS och de flesta Linux-verktyg rapporterar numera decimala GB, vilket stämmer med förpackningen. Minnesstorlekar är genuint binära, så 16 GB RAM är verkligen 16 GiB.
Nätverkshastigheter räknas i bitar, inte bytes, och alltid decimalt. En förbindelse på 100 Mbit/s bär 100 000 000 bitar per sekund, vilket är 12,5 MB per sekund före överhead. Protokollöverhead tar några procent, så 11 till 12 MB per sekund är det realistiska taket. Att dividera en annonserad megabitsiffra med åtta är den snabba kontrollen, och Unit Converter täcker lagringsenheterna.
Flyttal, och varför pengar inte är ett flyttal
Binära bråk kan bara representera summor av halvor, fjärdedelar, åttondelar och så vidare. En tiondel har ingen exakt binär form, på samma sätt som en tredjedel inte har någon exakt decimal form, så 0.1 lagrat som ett IEEE 754-dubbelprecisionstal är något mer än en tiondel. Addera två sådana approximationer och felet blir synligt:
0.1 + 0.2 = 0.30000000000000004
Ett dubbelprecisionstal har 53 bitars signifikand. Det gör varje heltal upp till 2^53 (9 007 199 254 740 992) exakt representerbart, tillsammans med varje bråk vars nämnare är en tvåpotens. Ovanför 2^53 blir glappet mellan representerbara värden 2, så 2^53 + 1 är lika med 2^53. Det är därför 64-bitars databasidentifierare som skickas genom JSON bör färdas som strängar: JavaScript-tal är dubbelprecisionstal, och ett ID med 19 siffror tappar tyst sina sista siffror.
För pengar, lagra hela minsta enheter (ören, cent) eller använd en decimaltyp som arbetar i bas tio. Jämför aldrig flyttal med likhet; jämför skillnaden mot en liten tolerans. Expression Calculator arbetar också i dubbelprecisionstal och ärver samma begränsningar.
Avrundning, och att avrunda två gånger
Uppåt vid hälften rundar exakt hälften bort från noll. Till jämnt vid hälften, även kallad bankirsavrundning, skickar exakt hälften till närmaste jämna siffra, vilket tar bort den uppåtriktade skevhet som uppåt vid hälften inför över en lång kolumn med siffror. Det är IEEE 754:s standard och regeln i flera redovisningsstandarder.
| Värde | Uppåt vid hälften | Till jämnt vid hälften |
|---|---|---|
| 0,5 | 1 | 0 |
| 1,5 | 2 | 2 |
| 2,5 | 3 | 2 |
| 3,5 | 4 | 4 |
| -0,5 | -1 | 0 |
Avrunda en gång, från originalvärdet. Att avrunda 2,4449 till tre decimaler ger 2,445, och att avrunda det till två ger 2,45, medan en avrundning av originalet direkt till två ger 2,44. Kedjad avrundning genom mellanliggande kolumner är en vanlig källa till summor som är fel på ett öre. En besläktad överraskning: 2,675 avrundas till 2,67 i de flesta språk, eftersom det lagrade dubbelprecisionstalet är 2,67499999999999982.
Procent och procentenhet
En andel som rör sig från 4 % till 5 % har stigit med en procentenhet, eller med 25 % relativt sett. Båda är korrekta, och enheten måste anges.
Procentuella förändringar tar inte ut varandra. Ett fall på 50 % följt av en uppgång på 50 % lämnar 75, inte 100, eftersom den andra procentsatsen tas från en mindre bas. Att återhämta ett fall på p kräver en uppgång på p / (1 - p), så ett fall på 50 % kräver 100 %, och ett fall på 80 % kräver 400 %. Successiva förändringar multipliceras och bildar en geometrisk följd snarare än en summa, vilket är den tillväxt Number Sequence modellerar.
Förändringen från ett gammalt värde till ett nytt är (new - old) / old x 100, vilket är vad Percentage Calculator rapporterar som en differens. Att räkna bort 20 % moms betyder att dividera med 1,2, inte att subtrahera 20 %. Att medelvärdesbilda procentsatser över grupper av olika storlek ger fel totalsiffra om inte medelvärdet viktas, och att Sum and Average visar en median bredvid medelvärdet gör skevheten synlig.
Tal formaterade för en språkinställning
Formatering är ett visningsbeslut, och den går inte att vända utan att språkinställningen är känd. 1.234 är ett och lite till i Storbritannien och ett tusen i Tyskland. 1,234 är tvärtom. Vissa språkinställningar grupperar med ett mellanslag eller en apostrof i stället.
| Språkinställning | 1234567.89 |
|---|---|
| en-GB, en-US | 1,234,567.89 |
| de-DE | 1.234.567,89 |
| fr-FR | 1 234 567,89 |
| de-CH | 1'234'567.89 |
| en-IN | 12,34,567.89 |
Indisk gruppering sätter den första avgränsaren efter tre siffror och sedan efter varannan siffra, vilket ger lakh och crore i stället för tusental och miljoner. Att tolka en formaterad sträng tillbaka till ett tal är förlustbehäftat av just detta skäl, så lagra och överför värden oformaterade med en punkt som decimaltecken, och formatera först vid visningen. Där ett tal måste vara entydigt för en läsare är det vanliga att skriva ut det med bokstäver med Number to Words, som på checkar och i avtal. Romerska siffror står utanför allt detta: utan platsvärde och utan nolla hanterar Roman Numeral Converter en streckräkning snarare än en bas.