| 07-02-2009, 05:47 PM | #1 |
This is a library that allows conversion of numbers from a decimal system into any other numeral system or vice verca by using these functions: function ConvertFromDec takes integer number, integer toBase returns string function ConvertToDec takes string number, integer fromBase returns integer For example ConvertFromDec(47, 5) will return "142" and ConvertToDec("FF", 16) will return 255. You should use the 0x prefix instead of base16 conversions though. This library might find use in code systems for example to shorten large integers to a few digits. If you rearrange or add more characters to the CHARACTER_SET constant this library itself might even work as some sort of low-level encryption. Requirements: - JassHelper (or any other vJass compiler) - StringLib by ToukoAozaki JASS:library BaseConversion initializer Init requires StringLib globals private constant string CHARACTER_SET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" private integer SetSize = StringLength(CHARACTER_SET) private string array Char private hashtable Values endglobals function ConvertFromDec takes integer number, integer toBase returns string local string s = "" local integer quo local integer div = number if toBase > SetSize then debug call BJDebugMsg(SCOPE_PREFIX+"ConvertFromDec: toBase > SetSize.") return "" endif if toBase <= 0 then debug call BJDebugMsg(SCOPE_PREFIX+"ConvertFromDec: toBase <= 0.") return "" endif if HaveSavedString(Values, toBase, number) then return LoadStr(Values, toBase, number) endif loop set quo = div/toBase set s = Char[div - quo * toBase] + s exitwhen quo == 0 set div = quo endloop call SaveStr(Values, toBase, number, s) return s endfunction function ConvertToDec takes string number, integer fromBase returns integer local string s local integer hash = StringHashCS(number) local integer i = 0 local integer dec = 0 if fromBase > SetSize then debug call BJDebugMsg(SCOPE_PREFIX+"ConvertToDec: fromBase > SetSize.") return 0 endif if fromBase <= 0 then debug call BJDebugMsg(SCOPE_PREFIX+"ConvertToDec: fromBase <= 0.") return 0 endif if HaveSavedInteger(Values, fromBase, hash) then return LoadInteger(Values, fromBase, hash) endif loop set s = SubString(number, i, i+1) exitwhen s == "" set dec = dec*fromBase + LoadInteger(Values, 0, StringHashCS(s)) set i = i+1 endloop call SaveInteger(Values, fromBase, hash, dec) return dec endfunction private function Init takes nothing returns nothing local integer i = 0 local string s set Values = InitHashtable() loop exitwhen i == SetSize set s = SubString(CHARACTER_SET, i, i+1) set Char[i] = s call SaveInteger(Values, 0, StringHashCS(s), i) set i = i+1 endloop endfunction endlibrary |
| 07-02-2009, 07:46 PM | #2 |
Use Table instead of own Hashtables/Game Caches. |
| 07-02-2009, 09:00 PM | #3 |
This could be very slow, depending on the actual speed of hashtables. The gamecache version is definitely to slow to be used a lot. And you should use Table for this. |
| 07-02-2009, 10:48 PM | #4 | |
Quote:
Speed issue cannot be dealt with JASS2. Too bad Blizz didn't allow access to individual characters... even read-only access could boost many things. |
| 07-02-2009, 11:18 PM | #5 |
I think it might be very convenient to store the return value to a hashtable after converting it once, then just recalling that value from the hashtable in the future if it's ever needed. This would only make it slow the first time and reduce it to a conditional + hashtable call thereafter. |
| 07-03-2009, 06:59 AM | #6 |
If you do what Rising_Dusk said, this could be useful for usage with typed commands. |
| 07-03-2009, 02:33 PM | #7 | |
Alright I added what Dusk said. I haven't been able to test it yet though, so if anyone is willing to test it for me (on a 1.23b client) I will be very thankful. Edit: Quote:
JASS:library BaseConversion initializer Init globals private constant string CHARACTER_SET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" private integer SetSize = StringLength(CHARACTER_SET) private string array Char private hashtable Values endglobals function ConvertFromDec takes integer number, integer toBase returns string local string s = "" local integer quo local integer div = number if toBase > SetSize then debug call BJDebugMsg(SCOPE_PREFIX+"ConvertFromDec: toBase greater than SetSize.") return 0 endif if toBase == 0 then debug call BJDebugMsg(SCOPE_PREFIX+"ConvertFromDec: toBase equals 0.") return 0 endif if HaveSavedString(Values, toBase, number) then return LoadStr(Values, toBase, number) endif loop set quo = div/toBase set s = Char[div - quo * toBase] + s exitwhen quo == 0 set div = quo endloop call SaveStr(Values, toBase, number, s) return s endfunction function ConvertToDec takes string number, integer fromBase returns integer local string s local integer hash = StringHash(number) local integer i = 0 local integer dec = 0 if fromBase > SetSize then debug call BJDebugMsg(SCOPE_PREFIX+"ConvertToDec: fromBase greater than SetSize.") return 0 endif if fromBase == 0 then debug call BJDebugMsg(SCOPE_PREFIX+"ConvertToDec: fromBase equals 0.") return 0 endif if HaveSavedInteger(Values, -fromBase, hash) then return LoadInteger(Values, -fromBase, hash) endif loop set s = SubString(number, i, i+1) exitwhen s == "" set dec = dec*fromBase + LoadInteger(Values, 0, StringHash(s)) set i = i+1 endloop call SaveInteger(Values, -fromBase, hash, dec) return dec endfunction private function Init takes nothing returns nothing local integer i = 0 local string s set Values = InitHashtable() loop exitwhen i == SetSize set s = SubString(CHARACTER_SET, i, i+1) set Char[i] = s call SaveInteger(Values, 0, StringHash(s), i) set i = i+1 endloop endfunction endlibrary @0zyx0: What are typed commands? |
| 07-03-2009, 02:55 PM | #8 |
Commands typed by players in the chat box. |
| 07-03-2009, 02:58 PM | #9 |
So it was that simple . Then I don't understand why it could be useful for that. Why should players want to convert anything they type into baseX numbers? |
| 07-03-2009, 04:46 PM | #10 |
It's the opposite, what they type in should be converted to an integer. And the variable you call hash should be an integer, not a string. |
| 07-03-2009, 05:12 PM | #11 | |
Quote:
Oh right. Fixed. Thanks. I should also add a debug message for negative bases as they might screw up the script pretty much. But I still don't see why you would want to convert chat messages to integers. You'd have to add loads of additional characters to cover all available bnet characters and the integers will be huge - much bigger than just saving the actual string. It might, however, be used as a reversable - and much more performance heavy - alternative to StringHash (unregistered characters will just act like 0 btw. For example "2_" base16 will convert into 32). It's main purpose is still of mathematical nature though. |
| 07-04-2009, 08:16 AM | #12 |
Save-load codes based on unit IDs, convert from base 26 or 36 or whatever the hell you want to use for your save-load codes and then to hexadecimal (Unit IDs). |
| 07-04-2009, 12:16 PM | #13 | |
Quote:
Yeah this is kinda what it's intended for. Or saving huge amounts of gold or even coordinates. A base62 (=0-9 + A-Z + a-z) conversion is pretty awesome if you think about it: 1 digit: up to 61 2 digits: up to 3843 3 digits: up to 238327 4 digits: up to 14776335 Who knows... maybe some day there will be RTS maps with save codes storing whole cities. |
| 07-04-2009, 01:49 PM | #14 | ||
Quote:
Quote:
|
| 07-07-2009, 05:25 PM | #15 |
I quite like the new one you posted, Opp. If you would update the first post with it, I think it is clean enough to be approved. Furthermore, I feel that with Vex's post, it is OK to use a library-private hashtable and not use Table at all. for the updated version. |
