Tässä olisi oma isolukukikkareeni. Merkkijonojen sijaan se säilöö luvut hassusti kokonaislukuja käyttäen jolloin laskiessa tulee vähemmän sähläämistä lukujen kanssa. Etuna pitäisi olla lähinnä nopeus. Kerto- ja jakolaskufunktioita en ole jaksanut tehdä mutta katsoo nyt jos viitsisin.
-kirjasta löytyvästä esimerkkikoodista, mutta pientä viilausta olen joutunut tekemään koska CoolBasic.
Koodissa oleva esimerkki tulostelee 100 ensimmäistä lukua fibonaccin lukujonosta.
Code: Select all
// BIG, Tuki isoille luvuille CoolBasicissa
// Tehnyt: Jasse 'KilledWhale' Lahdenperä
// v. 0.3
//
// Init_BIG() Luo uuden jättiluvun
// Copy_BIG(big) Kopioi jättiluvun ja palauttaa luodun kopion
// Destroy_BIG(big) Poistaa jättiluvun muistista
// Set_BIG_INT(big, int) Asettaa jättiluvun arvoksi kokonaisluvun
// Add_BIG_BIG(big, big) Lisää jättilukuun jättiluvun ja palauttaa vastauksena uuden jättiluvun
// Sub_BIG_BIG(big, big) Vähentää jättiluvun jättiluvusta ja palauttaa vastauksena uuden jättiluvun
// String_BIG(big) Palauttaa jättiluvun merkkijonona
// Print_BIG(big) Tulostaa jättiluvun ruudulle
// ASETUKSET
Const RESERVE = 1000 // Montako lohkoa varataan oletuksena ( yksi lohko = 9 merkkiä )
// Näihin ei tarvitse koskea
Const PLUS = 0
Const MINUS = 1
////////////////////////////////////////////
// ESIMERKKIKOODI
////////////////////////////////////////////
a = Init_BIG()
b = Init_BIG()
Set_BIG_INT(a, 0)
Print "1: " + String_BIG(a)
Set_BIG_INT(b, 1)
Print "2: " + String_BIG(b)
For i = 3 To 100
c = Add_BIG_BIG(a, b)
Print i + ": " + String_BIG(c)
Destroy_BIG(a)
a = b
b = c
Wait 250
Next i
WaitKey
////////////////////////////////////////////
// FUNKTIOT (ÄLÄ KOSKE KUN ET KUITENKAAN TIEDÄ MITÄ TEET)
////////////////////////////////////////////
Function Init_BIG()
a = MakeMEMBlock(5 + RESERVE * 4)
PokeInt a, 0, 0
PokeByte a, 4, PLUS
Return a
EndFunction
Function Copy_BIG(big As Integer)
a = MakeMEMBlock(MEMBlockSize(big))
MemCopy big, 0, a, 0, MEMBlockSize(big)
Return a
EndFunction
Function Destroy_BIG(big As Integer)
DeleteMEMBlock big
EndFunction
Function Set_BIG_INT(big As Integer, num As Integer)
If num < 0
neg = 1
num = Abs(num)
EndIf
PokeInt big, 5, num Mod 1000000000
If num >= 1000000000 Then
PokeInt big, 9, RoundDown(num / 1000000000)
PokeInt big, 0, 2
Else
PokeInt big, 0, 1
EndIf
PokeByte big, 4, neg
EndFunction
Function Add_BIG_BIG(big1 As Integer, big2 As Integer)
asign = PeekByte(big1, 4)
bsign = PeekByte(big2, 4)
If asign = bsign Then
csign = asign
Else
If asign = MINUS Then
PokeByte big1, 4, PLUS
big3 = Sub_BIG_BIG(big2, big1)
PokeByte big1, 4, MINUS
Else
PokeByte big2, 4, PLUS
big3 = Sub_BIG_BIG(big1, big2)
PokeByte big2, 4, MINUS
EndIf
Return big3
EndIf
big3 = Init_BIG()
size = Max(PeekInt(big1, 0), PeekInt(big2, 0))
carry = 0
i = 1
While i <= size Or carry
a = PeekInt(big1, 1 + i * 4)
b = PeekInt(big2, 1 + i * 4)
PokeInt big3, 1 + i * 4, (carry + a + b) Mod 1000000000
carry = RoundDown((carry + a + b) / 1000000000)
i = i + 1
Wend
PokeInt big3, 0, i - 1
PokeByte big3, 4, csign
Return big3
EndFunction
Function Sub_BIG_BIG(big1 As Integer, big2 As Integer)
asign = PeekByte(big1, 4)
bsign = PeekByte(big2, 4)
If asign = MINUS Or bsign = MINUS Then
PokeByte big2, 4, (bsign = PLUS) * MINUS + (bsign = MINUS) * PLUS
big3 = Add_BIG_BIG(big1, big2)
PokeByte big2, 4, bsign
Return big3
EndIf
If Comp_BIG_BIG(big1, big2) = 1 Then
big3 = Sub_BIG_BIG(big2, big1)
PokeByte big3, 4, MINUS
Return big3
EndIf
big3 = Init_BIG()
size = Max(PeekInt(big1, 0), PeekInt(big2, 0))
borrow = 0
For i = 1 To size
v = PeekInt(big1, 1 + i * 4) - borrow - PeekInt(big2, 1 + i * 4)
If PeekInt(big1, 1 + i * 4) > 0 Then borrow = 0
If v < 0 Then
v = v + 1000000000
borrow = 1
EndIf
PokeInt big3, 1 + i * 4, v Mod 1000000000
Next i
PokeInt big3, 0, size
Return big3
EndFunction
Function Comp_BIG_BIG(big1 As Integer, big2 As Integer)
asign = PeekByte(big1, 4)
bsign = PeekByte(big2, 4)
asize = PeekInt(big1, 0)
bsize = PeekInt(big2, 0)
asgn = (asign = PLUS) - (asign = MINUS)
If asign = MINUS And bsign = PLUS Then Return 1
If asign = PLUS And bsign = MINUS Then Return -1
If bsize > asize Then Return asgn
If asize > bsize Then Return -1 * asgn
For i = asize To 1 Step -1
If PeekInt(big1, 1 + i * 4) > PeekInt(big2, 1 + i * 4) Then Return asgn * -1
If PeekInt(big2, 1 + i * 4) > PeekInt(big1, 1 + i * 4) Then Return asgn
Next i
EndFunction
Function String_BIG(big As Integer)
If PeekByte(big, 4)
ret$ = "-"
EndIf
size = PeekInt(big, 0)
For i = size To 1 Step -1
a$ = Str(PeekInt(big, 1 + i * 4))
a$ = String("0", (9 - Len(a$)) * (i <> size)) + a$
ret$ = ret$ + a$
Next i
Return ret$
EndFunction
Function Print_BIG(big As Integer)
Print String_BIG(big)
EndFunction