[ Yoba @ 10.04.2010. 18:46 ] @
Kako da se resim u VB6 overflowa

a = 962500
d = 4558
res = a * d


i skuca mi se kod linije res?
[ Marko_L @ 10.04.2010. 19:06 ] @
Kad radiš sa velikim vrednostima, koristi Double ili Currency tip podataka. Long ne može da sadrži tolike vrednosti. Ovako će raditi
Code:
Dim a As Double
Dim d As Double
Dim res As Double

a = 962500
d = 4558
res = a * d
[ Shadowed @ 10.04.2010. 19:06 ] @
Necu ti reci direktno resenje, ali ako se potrudis i iskoristis ono sto ti kazem, imaces mnogo vise koristi dugorocno gledano:

Koristi strongly-typed programiranje.


Edit: Pretece me Marko i pokvari mi koncept :P
[ Yoba @ 10.04.2010. 23:35 ] @
hm...sada kada sam prekopirao radi.

inace i ja sam bio deklarisao varijable, kako se zapoveda, ali nije htelo :)

//evo sada sam nasao moj code

Code:

Dim a As Integer
Dim d As Integer
Dim res As Double

a = 962500
d = 4558
res = a * d



ako je buferoverflow na res (a i kod mene i kod Marka je na Double), kakve ima veze a i b (jer su meni Integer a kod Marka Double)

?
[ t.marko016 @ 10.04.2010. 23:45 ] @
Pa tebi nije overflow na "res" vec na "a".
[ Yoba @ 10.04.2010. 23:51 ] @
ali kada stavim a i b na Long onda je na res
[ t.marko016 @ 11.04.2010. 00:03 ] @
Probaj sledece:
Code:

Dim a As Long
Dim d As Long

a = 962500
d = 4558

Print a * d

Sad ovo je moja pretpostavka nemoj da me uzmes za rec:
Verovatno pre nego sto se pomnoze ta dva broja u res uzme se u obzir kog su tipa i onda se toliko odvoji prostor za njih u res.
[ Marko_L @ 11.04.2010. 11:19 ] @
Citat:
ako je buferoverflow na res (a i kod mene i kod Marka je na Double), kakve ima veze a i b (jer su meni Integer a kod Marka Double)

?

U tom primeru gde si deklarisao a i d kao Integer, dobijaš overflow na a = 962500 zato što pokušavaš da dodeliš toj varijabli veću vrednost nego što integer može da sadrži. U ovom slučaju to je 962500, a integer ne može biti veći od 32767, niti manji od -32768. Kada ih deklarišeš kao long, onda može, međutim onda ti javlja overflow kod res, jer ti kad množiš dve long varijable, vb očekuje da i rezultat bude long, pa toliko mesta odvaja u memoriji, međutim kako je rezultat veći od onoga što long može da sadrži (u ovom slučaju 4.387.075.000, a long ne može da sadrži vrednosti veće od 2.147.483.647, niti manje od -2.147.483.648), dobijaš overflow grešku. To nema nikakve veze sa time kog je tipa res varijabla, jer uopšte i ne dolazi do pokušaja smeštanja u istu. To možeš proveriti tako što ćeš potpuno eliminisati res varijablu i pokušati da prikažeš rezultat koristeći MsgBox recimo, ili Print kao u primeru koji je postavio t.marko016 (koji btw, takođe neće raditi upravo zbog ovoga o čemu pričam). Dakle, da bi izbegao overflow, barem jedna od varijabli koje se množe mora biti nekog tipa koji podržava veće vrednosti, a to su Double, Decimal, Currency...

Dakle, da rezimiramo... kako god okreneš, ako izvodiš bilo kakvu računsku operaciju sa long varijablama, i rezultat mora biti u opsegu koji long podržava. Ukoliko se očekuje veća vrednost, barem jedna od varijabli koju množiš mora biti tipa koji će podržati tu vrednost.

Dakle, ovo
Code:
Dim a As Long
Dim d As Long

a = 962500
d = 4558
Msgbox a * d

ili ovo
Code:
Dim a As Long
Dim d As Long

a = 962500
d = 4558
Print a * d

ili ovo
Code:
Dim a As Long
Dim d As Long
Dim res As Double

a = 962500
d = 4558
res = a * d

izbaciće overflow na poslednjoj liniji. Međutim ako makar jednu varijablu deklarišeš kao Double, izbećićeš overflow. Dakle, ovo
Code:
Dim a As Double
Dim d As Long
Dim res As Double

a = 962500
d = 4558
res = a * d

će raditi bez problema. Takođe, ako baš hoćeš da varijable budu Long, možeš da izvršiš konverziju u letu
Code:
Dim a As Long
Dim d As Long
Dim res As Double

a = 962500
d = 4558
res = CDbl(a) * d

i to će takođe raditi, mada treba imati u vidu da je konverzija u letu obično sporija, nego kada se varijabla deklariše na početku, pogotovo ako se računska operacija obavlja više puta zaredom, recimo u nekoj petlji.

A razlog zašto sam ja u mom primeru obe varijable deklarisao kao Double je takođe iz tog razloga, tj. dobijanja na brzini, jer obično je sporije kada se množe dve varijable različitog tipa, nego kada su one istog tipa i to iz razloga što kad množiš dve varijable različitog tipa, vb svakako mora da odradi konverziju te jedne varijable, pa opet dobijaš konverziju u letu. Upravo zato je najsporija varijanta kada su obe varijable tipa Long, jer onda imaš dve konverzije u letu (jednu koju si ti programski odradio i drugu koju vb mora sam da odradi zbog tvoje konverzije). Naravno, ne govorimo o nekim astronomskim razlikama u brzini, i na ovom primeru sa današnjim računarima se i ne može primetiti neka razlika (osim preciznim benchmarkom). Međutim, kada postoji potreba da se izvrši veliki broj računskih operacija (tipa 100.000 ili 1.000.000 ili 1.000.000.000 operacija), razlika može biti od nekoliko sekundi, pa do nekoliko minuta, ako ne i više, a ako se budete ozbiljno bavili programiranjem, doći ćete u takvu situaciju kad tad, tako da valja naučiti kako pravilno iskoristiti varijable. Ni ja do pre nekoliko godina nisam poklanjao previše pažnje tome, tj. kako će biti deklarisane varijable, da li će biti konverzacija u letu i slično, sve dok nisam naleteo na projekat u kome je bilo potrebno izvršiti jako veliki broj računskih operacija, pa pošto je to trajalo nesnosno dugo, bacio sam se na istraživanje i posle nekog vremena uspeo da izbacivanjem konverzija u letu i optimalnim deklarisanjem varijabli skratim proces za skoro 30 minuta, što nije mali vremenski period. Kad kažem optimalno, to ne znači da će se varijable koje mogu da sadrže manje vrednosti tipa Integer, brže množiti ili sabirati od varijabli sa većim vrednostima, tipa Long. Naprotiv, na 32-bitnim mašinama se operacije sa Long varijablama brže izvršavaju nego one sa Integer varijablama. No, to su već finese u koje nećemo sad ulaziti, a ako vam ikada bude trebalo imate dosta tih stvari po netu, a uvek možete da uradite sopstvene benchmark testove i utvrdite šta će najbrže raditi.

[Ovu poruku je menjao Marko_L dana 11.04.2010. u 12:45 GMT+1]
[ Yoba @ 11.04.2010. 12:19 ] @
Super, sve si mi objasnio, imas rucicu na gore :)


//btw nemoj da mi persiras ;)