Author | Message |
---|
Meka][Meka Unstopable Posts: 700
| anyone see why this aint working??
Code: | procedure ShowByteSize; var i : Integer; s : string; begin if ComboBox1.Text = 'B' then i := StrToInt(Edit4.Text) else if ComboBox1.Text = 'KiB' then i := StrToInt(Edit4.Text) * 1024 else if ComboBox1.Text = 'MeB' then i := (StrToInt(Edit4.Text) * 1024) * 1024 else if ComboBox1.Text = 'GiB' then i := ((StrToInt(Edit4.Text) * 1024) * 1024) * 1024 else if ComboBox1.Text = 'TeB' then i := (((StrToInt(Edit4.Text) * 1024) * 1024) * 1024) * 1024 else if ComboBox1.Text = 'PeB' then i := ((((StrToInt(Edit4.Text) * 1024) * 1024) * 1024) * 1024) * 1024; s := IntToStr(i); ShowMessage(s); end; |
|
Mickey Ametuar Posts: 115
| The problem is [u:89b728186d]overflow in conversions or arithmetic operations[/u:89b728186d]. Watch aritmetic ranges. Using Integer you can store max 2GB - 1 byte = 2147483647 Bytes!!! = 2^31-1 ~~ 2.14 * 10^9 1PeB = 1125899906842624 Bytes = 2^50 ~~ 1.12 * 10^15 Having a look at the table below which is from Delphi Help we realize we should use Int64 to store PeB big numbers: Generic integer types for 32-bit implementations of Delphi Type / Range / Format Integer : -2147483648..2147483647 signed 32-bit Cardinal : 0..4294967295 unsigned 32-bit Fundamental integer types include Shortint, Smallint, Longint, Int64, Byte, Word, and Longword. Fundamental integer types Type / Range / Format Shortint : -128..127 signed 8-bit Smallint : -32768..32767 signed 16-bit Longint : -2147483648..2147483647 signed 32-bit Int64 : -2^63..2^63-1 signed 64-bit Byte : 0..255 unsigned 8-bit Word : 0..65535 unsigned 16-bit Longword : 0..4294967295 unsigned 32-bit Let's try the code now. I shortened a bit. I could see a lot of parenthesis which could be neglected due to the fact multiplication is commutative and associative. Of course it is not a problem but why not to make it shorther? So it can be something like this:
Code: | procedure TForm1.ShowByteSize; var i : Int64; s : string; begin i := StrToInt(Edit4.Text); if ComboBox1.Text = 'KiB' then i := i * 1024 else if ComboBox1.Text = 'MeB' then i := i * 1024 * 1024 else if ComboBox1.Text = 'GiB' then i := i * 1024 * 1024 * 1024 else if ComboBox1.Text = 'TeB' then i := i * 1024 * 1024 * 1024 * 1024 else if ComboBox1.Text = 'PeB' then i := i * 1024 * 1024 * 1024 * 1024 * 1024; s := IntToStr(i); ShowMessage(s); end; | It hasn't worked yet :( The problem is: Try to paste this in your code anywhere and compille:
Code: | i := 1 * 1024 * 1024 * 1024; // This is OK and can be calculated i := 2 * 1024 * 1024 * 1024; // Overflow :( | Error: Overflow in conversion or arithmetic operation. You'll get error at compillation. It seems that Delphi built in routines cannot multiply such big numbers :( Too bad. Solution: We need to make our own multiplying routine for big numbers. I could see some cool maths routines I got from www.torry.net. If you cannot find tell me and I'll have a look. I hope it helped. Good luck.
|
Meka][Meka Unstopable Posts: 700
| yep i had tried the in64 and still had the same problem, i guessed it was a delphi problem, but wanted to make sure, thanks...
|
Meka][Meka Unstopable Posts: 700
| ok i've messed around for 10mins and finally came to the concliusion its my fault, so i have finally found the error i (we) was making...
Code: | procedure ShowByteSize; var i : Extended; s : String; begin if ComboBox1.Text = 'B' then i := StrToFloat(Edit1.Text) else if ComboBox1.Text = 'KiB' then i := StrToFloat(Edit1.Text) * 1024 else if ComboBox1.Text = 'MeB' then i := (StrToFloat(Edit1.Text) * 1024) * 1024 else if ComboBox1.Text = 'GiB' then i := ((StrToFloat(Edit1.Text) * 1024) * 1024) * 1024 else if ComboBox1.Text = 'TeB' then i := (((StrToFloat(Edit1.Text) * 1024) * 1024) * 1024) * 1024 else if ComboBox1.Text = 'PeB' then i := ((((StrToFloat(Edit1.Text) * 1024) * 1024) * 1024) * 1024) * 1024; s := FloatToStr(i); ShowMessage(s); end; | -/Meka][Meka
|
Mickey Ametuar Posts: 115
| Cool. 8) Of course, you don't need to use integers. Sorry for not mentioning that. Anyway if I want fast code I would use Integers with some asm multiply routines but here is not needed. This way you did is easier. If you omit those parenthesis as I did abobe would be nicer but it is up to you. :wink:
Code: | procedure TForm1.ShowByteSize; var i : Extended; s : string; begin i := StrToFloat(Edit4.Text); if ComboBox1.Text = 'KiB' then i := i * 1024 else if ComboBox1.Text = 'MeB' then i := i * 1024 * 1024 else if ComboBox1.Text = 'GiB' then i := i * 1024 * 1024 * 1024 else if ComboBox1.Text = 'TeB' then i := i * 1024 * 1024 * 1024 * 1024 else if ComboBox1.Text = 'PeB' then i := i * 1024 * 1024 * 1024 * 1024 * 1024; s := FloatToStr(i); ShowMessage(s); end; |
|
bluebear n00b Posts: 32
| ^^^If its calculations that are done often; for example in the userlist of a client wich updates alot. I would use bitwise operations instead much faster' Cpp ->
Code: | #ifdef __BORLANDC__ #pragma argsused int main( int argc, char * argv[] ) { unsigned long result, bytes; bytes = 792723456; /* 756 Mbytes */ /* Normal calcs */ result = ( bytes / 1024 ); /* bytes to kbytes */ cout << "Normal calc: " << result << " KB" << endl; result = ( ( bytes / 1024 ) / 1024 ); /* bytes to mbytes */ cout << "Normal calc: " << result << " MB" << endl; // bitwise result = bytes >> 10; /* bytes to kbytes */ cout << "Bitwise calc: " << result << " KB" << endl; result = bytes >> 20; /* bytes to mbytes */ cout << "Bitwise calc: " << result << " MB" << endl; return 0; } |
|
Meka][Meka Unstopable Posts: 700
| ah but remember this is pascal section, and, i only need it to check once in a while, when i click check button thanks neways
|
Mickey Ametuar Posts: 115
| Yep BlueBear how right you are. Working on numbers with base 2 and 16 we can use shift operators: shl - bitwise shift left (division) shr - bitwise shift right x shl 10 = x * (2^10) = x*1024 x shl 20 = x * (2^20) = x*1024*1024 etc. Shifting is the fastest way, faster than multiplication. The code would be this:
Code: | procedure ShowByteSize; var i : Int64; s : string; begin i := StrToInt(Edit4.Text); if ComboBox1.Text = 'KiB' then i := i shl 10 else if ComboBox1.Text = 'MeB' then i := i shl 20 else if ComboBox1.Text = 'GiB' then i := i shl 30 else if ComboBox1.Text = 'TeB' then i := i shl 40 else if ComboBox1.Text = 'PeB' then i := i shl 50; s := IntToStr(i); ShowMessage(s); end; |
|