Numrat

Numrat ndahen në dy lloje kryesore:

  • Numra të plotë (integers), dhe
  • Numra me presje dhjetore (floating-point numbers).

Numrat e plotë

Numrat e plotë janë numra pa komponentën decimale. Të gjithë numrat e plotë kanë madhësi të caktuar kur ruhen apo procesohen në kompjuter.

Për shembull, një bajt (byte) përbëhet nga 8 bita, ku secili bit mund ta ketë vlerën 0 ose 1.
Kështu, në një bajt (8 bit) mund të ruhen 256 (28) vlera të ndryshme pozitive, prej 0 deri 255, respektivisht prej 00000000 deri 11111111 nëse e shprehim numrin në formë binare.

Nëse duhet ta ruajmë një numër pozitiv më të madh se 255, na nevojitet edhe një bajt tjetër, pra gjithsej 2 bajtë (16 bit). Në këtë rast, vlerat do të shkojnë nga 0000000000000000 deri në 1111111111111111, që në numra me bazë 10 do të jetë nga 0 deri në 65.535, pra gjithsej 65.536 vlera (216).

Me katër bajtë (32 bit), diapazoni i vlerave pozitive është 0 deri në 4.294.967.295, gjithsej 4.294.967.296 vlera (232), e kështu me radhë, për çdo bajt të shtuar diapazoni i vlerave zgjerohet 256 herë.

Kur duhet të ruhen numrat e plotë negativë, biti i parë i bajtit të parë (most significant bit) shfrytëzohet si indikator: vlera 0 tregon se është vlerë pozitive, ndërsa vlera 1 se është vlerë negative, prandaj diapazoni i vlerave përgjysmohet, ashtu siç është paraqitur në tabelë.

Kur ruajmë vetëm vlera pozitive, kemi të bëjmë me unsigned integers, ndërsa për pozitive dhe negative – signed integers.
Tipet e numrave të plotë, emrat e të cilëve fillojnë me u janë tipe pa parashenjë (unsigned types), të cilat përmbajnë vetëm vlera jonegative.

Numri pas emrit tregon numrin e bitave binarë (8, 16, 32, 64) që nevojiten për ruajtjen e vlerës në memorje. Për shembull uint8 zbërthehet si: numër i plotë jonegativ që okupon 8 bit në memorje, me çka mund të reprezentohen vlerat prej 0 deri 255 (28-1). Ndërsa tipi int8: numër i plotë që okupon 8 bit n memorje dhe merr vlera prej -128 (-27) deri në 127 (27-1).

Vlera jonegative (unsigned)

  • Bit: 8, Bajt:1, Prej: 0, Deri: 255 (28-1)
  • Bit: 16, Bajt:2, Prej: 0, Deri: 65.535 (216-1)
  • Bit: 32, Bajt:4, Prej: 0, Deri: 4.294.967.295 (232-1)
  • Bit: 64, Bajt:8, Prej: 0, Deri: 18.446.744.073.709.551.615 (264-1)

Vlera negative dhe jonegative (signed)

  • Bit: 8, Bajt:1, Prej: -128 (-27), Deri: 127 (27-1)
  • Bit: 16, Bajt:2, Prej: -32.768 (-215), Deri: 32,767 (215-1)
  • Bit: 32, Bajt:4, Prej: -2.147.483.648 (-231), Deri: 2.147.483.647 (231-1)
  • Bit: 64, Bajt:8, Prej: -9.223.372.036.854.775.808 (-263), Deri: 9,223,372,036,854,775,807 (263-1)

Go përdor tipet vijuese të numrave të plotë:

8 bitë unsigned

  • uint8 (byte)

16 bitë unsigned

  • uint16

32 bitë unsigned

  • uint32
  • uint
  • uintptr

64 bitë unsigned

vlera maksimale e int8 ësh
8 bitë signed

  • int8

16 bitë signed

  • int16

32 bitë signed

  • int32 (rune)
  • int

64 bitë signed

ë vlerës maksimal
Tipi byte është alias i uint8, d.m.th. janë të njëjtë.

Tipi rune është alias i int32.

Madhësitë e tipeve uint, int dhe uintptr varen nga platforma, respektivisht arkitektura e procesorit; në platformat 32 bitëshe kanë madhësi 32 bitëshe, ndërsa në platformat 64 bitëshe - madhësi 64 bitëshe.
Madhësia e vlerës uintptr duhet të jetë mjaft e madhe që të ruajë bitat e painterpretuar të një adrese memorike.

Duhet të kemi parasysh që vlerat që ia japim një tipi t’i përgjigjen diapazonit të vlerave të lejuara për atë tip. Për shembull, tipi int8 mund të përmbajë vlera prej -128 deri 127. Nëse në program i japim një vlerë më të madhe se 127 apo më të vogël se -128, kompajleri do të lajmërojë gabim dhe programi nuk do të kompajlohet fare.

1 var muaji int8
2 muaji = 500

Mirëpo, nëse vlera e një tipi caktohet gjatë ekzekutimit të programit, me ç’rast kompajleri nuk e di paraprakisht vlerën, do të ndodhin situata konfuze, me ç’rast programi nuk lajmëron gabim por ndodh overflow. Për shembull, meqë vlera maksimale e int8 është 127 dhe nëse gjatë kohës së ekzekutimit merr vlerën 128, vlera rezultuese do të jetë -127! Kjo për shkak se pas arritjes së vlerës maksimale, programi fillon prej vlerës më të vogël për aq sa sa vlera e re dallon nga vlera maksimale.

Me fjalë të tjera, nëse int8 merr vlerën 150, në fakt ai do ta ketë vlerën -105 sepse 150-127=23 dhe -128+23 = -105. Ky mund të jetë burim vështirë i detektueshëm i gabimeve në rezultatet e programit sepse sistemi i kohës së ekzekutimit (runtime system) i Go nuk do të na lajmërojë për ndonjë gabim eventual.

Duhet të kemi parasysh edhe faktin që ndaj numrave të plotë të tipeve të ndryshme nuk mund të kryejmë operacione aritmetikore. Për shembull, nuk mund ta mbledhim një numër të tipit uint8 me një numër të tipit int16. Për ta realizuar operacionin e mbledhjes, të dy tipet duhet më parë t’i konvertojmë në një tip të njëjtë e më pas ta kryejmë veprimin aritmetikor. Në shembullin vijues, konvertimi bëhet në tipin int nëpërmes funksionit int(), i cili ka madhësinë 32 apo 64 bitë, në varësi prej arkitekturës, por gjithsesi është më i madh se 8 bitë (tipi uint8) dhe 16 bitë (int16).

 1 var m uint8
 2 m = 5
 3 var f int16
 4 f = 6
 5 
 6 var n int
 7 // kjo shkakton gabim kompajlimi
 8 n = m + f
 9 // prandaj variablat m dhe f duhet te konvertohen
10 // me funksionin int()
11 n = int(m) + int(f)

Numrat me presje dhjetore

Numrat me presje dhjetore (floating-point numbers) janë numra që përmbajnë komponentën decimale. Paraqitja e tyre në kompjuter është më e ndërlikuar se e numrave të plotë. Kjo bën që saktësia e këtyre numrave të jetë e kufizuar dhe rrjedhimisht edhe e llogaritjeve që bëhen me këto numra.

Në memorje, të gjitha vlerat e numrave me presje dhjetore ruhen në formatin IEEE-754.

Numrat me presje dhjetore kanë madhësi (numra bitash) të caktuar, 32 bitë (single precision) apo 64 bitë (double precision), sikurse edhe numrat e plotë.

Numrat më të mëdhenj kanë saktësi më të vogël, sepse duke qenë se kanë madhësi fikse (32/64 bitë), sa më e madhe pjesa e plotë, aq më pak shifra ngelen në dispozicion djathtas prej presjes dhjetore, me çka zvogëlohet saktësia e pjesës decimale.

Mund të përmbajnë edhe vlera jonumerike siç janë:

  • NaN (not a number)
  • Infinit pozitiv (+∞)
  • Infininit negativ (−∞)

Shembull me infinit:

 1 package main
 2 
 3 import (
 4 	"fmt"
 5 )
 6 
 7 func main() {
 8 	var c float32 = 0
 9 	var d float32 = 0
10 
11 
12 	var a float32 = 24
13 	d = a / c
14 	fmt.Printf("result = %.2f \n", d)
15 
16 	var b float32 = -15
17 	d = b / c
18 	fmt.Printf("result = %.2f \n", d)
19 }

https://play.golang.org/p/ZrzSGo-MnzA

Rezultati:


result = +Inf
result = -Inf

Go ka dy tipe për paraqitjen e numrave kompleksë:

  • complex64, dhe
  • complex128.

Pjesa reale dhe imagjinare e një vlere complex64 janë të dyja vlera float32, ndërsa pjesët reale dhe imagjinare të një vlere complex128 janë të dyja vlera float64.

Në Go përdoren operatorët standard vijues:

  • Mbledhja +
  • Zbritja -
  • Shumëzimi *
  • Pjestimi /
  • Modulusi %