HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

BaseConversion

07-02-2009, 05:47 PM#1
Opossum
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
Expand JASS:
07-02-2009, 07:46 PM#2
Mr.Malte
Use Table instead of own Hashtables/Game Caches.
07-02-2009, 09:00 PM#3
0zyx0
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
ToukoAozaki
Quote:
Originally Posted by 0zyx0
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.

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
Rising_Dusk
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
0zyx0
If you do what Rising_Dusk said, this could be useful for usage with typed commands.
07-03-2009, 02:33 PM#7
Opossum
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:
<Opossum> uh when using the same parent and child keys in a hashtable for two different types (e.g. string and integer) will they overwrite each other?
<Blubb-Tec> think blizz wrote that somewhere
<Blubb-Tec> but yes, they overwrite
<Blubb-Tec> afaik
Changed the parent keys to negative values for ToDec conversions to keep them seperated. Thanks to Blubb-Tec.
Collapse 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
I'm not using Table in this version because I have to make my own hashtable for the "ConvertFromDec" return values anyway. I probably should have used Table in the initial version though.

@0zyx0: What are typed commands?
07-03-2009, 02:55 PM#8
0zyx0
Commands typed by players in the chat box.
07-03-2009, 02:58 PM#9
Opossum
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
0zyx0
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
Opossum
Quote:
Originally Posted by 0zyx0
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.

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
Tide-Arc Ephemera
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
Opossum
Quote:
Originally Posted by Tide-Arc Ephemera
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).

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
Vexorian
Quote:
Originally Posted by 0zyx0
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.
Depends what's your definition of slow. In this case hashtables or even gamecache are still faster than the alternatives, so...

Quote:
Use Table instead of own Hashtables/Game Caches.
It was a necessity for Table or a central GC in the case of gamecache, but it is ok to use a unique, private hashtable .
07-07-2009, 05:25 PM#15
Rising_Dusk
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.