String <-> Int

For scripting examples for learning how to use AMXX.
User avatar
Archive-Poster
Posts: 1229
Gender:
United States of America

String <-> Int

Post by Archive-Poster »

Code: Select all

// Valid radix can be anything from 2 to 36.

#define Binary  2
#define Ternary  3
#define Trinary  3
#define Quintal  5
#define Oct   8
#define Octal  8
#define Dec   10
#define Decimal  10
#define Duodecimal 12
#define Dozenal  12
#define Hex   16
#define Hexadecimal 16

new ___key[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define ___ctod(%0) ('0' <= %0 <= '9' ? %0 - '0' : 'A' <= %0 <= 'Z' ? %0 -'A' + 10 : 'a' <= %0 <= 'z' ? %0 -'a' + 10 : 0)

// Converts an integer to a string.
stock itoa(val, out[], len, radix = Decimal) {
 
 if ( ! val ) { out[0] = '0'; out[1] = 0; return; }
 if ( ! ( 2 <= radix <= 36 ) ) { out[0] = '0'; out[1] = 0; return; }
 
 for ( new i = len ; i ; i-- ) { out[i] = 0; }
 
 for ( new i = len - 1 ; val && i > -1 ; --i, val /= radix )
  out[len-i-1] = ___key[val % radix];
 
 new len2 = strlen(out);
 new temp;
 
 for ( new i = 0 ; i < len2 / 2 ; i++ ) {
  temp = out[i];
  out[i] = out[len2-i-1];
  out[len2-i-1] = temp;
 }
}

// Converts a string to an integer.
stock atoi(string[], radix = Decimal) {
 
 if ( ! ( 2 <= radix <= 36 ) ) { return 0; }
 
 new result, mult = 1;
 
 for ( new i = strlen(string) - 1 ; i > - 1 ; i-- ) {
  result += ___ctod(string[i]) * mult;
  mult *= radix
 }
 
 return result;
}
User avatar
Archive-Poster
Posts: 1229
Gender:
United States of America

Re: String <-> Int

Post by Archive-Poster »

str_to_num(), num_to_str() -> faster!
edit: at least for decimals!
buildin function converted only decimal digits.
This functions convert on any radix.
I believe this is not correct:

Code: Select all

( 2 > radix > 36 ) 
One thing:

Code: Select all

result += mult == 1 ? ___ctod(string[i]) : ___ctod(string[i]) * mult; 
should be

Code: Select all

result += ___ctod(string[i]) * mult; 
You are doing a comparison on every iteration on the loop that you dont need because ___ctod(string) = ___ctod(string) * 1


I don't see why radix check is wrong...

The second is a miss, i used power() then changed to increasing multiplier. I didn't notice that wasn't needed anymore.

If you're on a very limited internet connection and want to send data you can even optimize SHORT strings (5 chars, 6 if low char values).

Code: Select all

 new test_string[1024] = "TEST69";
 num = atoi(test_string, test_radix);
 itoa(num, test, 1023, test_radix);
 server_print("%s = %d = %s", test_string, num, test);

Code: Select all

TEST69 = 1778377905 = TEST69
or longer strings...

Code: Select all

 new test_string[128] = "WHATTHEHELLISTHISMADOPTIMIZINGTHINGY";
 
 
 new temp_array[32];
 new temp_str[10];
 
 
 new len;
 new result_str[128];
 
 
 server_print("Original string: %s", test_string);
 
 
 for ( new i ; i < strlen(test_string) ; i+=5 ) {
  formatex(temp_str, 5, "%s", test_string[i]);
  temp_array[floatround(i / 5.0, floatround_floor)] = atoi(temp_str, 36);
  server_print("temp_array[%d] = %d", floatround(i / 5.0, floatround_floor), temp_array[floatround(i / 5.0, floatround_floor)]);
 }
 
 
 for ( new i ; i < strlen(temp_array) ; i++ ) {
  itoa(temp_array[i], temp_str, 5, 36);
  len += formatex(result_str[len], 127 - len, "%s", temp_str);
 }
 
 
 server_print("Generated string: %s", result_str);

Code: Select all

Original string: WHATTHEHELLISTHISMADOPTIMIZINGTHINGY
temp_array[0] = 54554897
temp_array[1] = 29229213
temp_array[2] = 36149093
temp_array[3] = 31568341
temp_array[4] = 41515438
temp_array[5] = 31890220
temp_array[6] = 49526188
temp_array[7] = 34
Generated string: WHATTHEHELLISTHISMADOPTIMIZINGTHINGY
When I finish the float version this can be used for longer strings, but probably not in PAWN since the floats are so inaccurate.

Either way, it's not worth it. But it is possible.
User avatar
Archive-Poster
Posts: 1229
Gender:
United States of America

Re: String <-> Int

Post by Archive-Poster »

I don't see why radix check is wrong...
It should look like this:

Code: Select all

( !( 2 <= radix <= 36 ) )
The result is the same.
Either way works for me, but if you're so damn picky...
User avatar
Archive-Poster
Posts: 1229
Gender:
United States of America

Re: String <-> Int

Post by Archive-Poster »

The question is that this:

Code: Select all

( 2 > radix > 36 ) 
Reads:

radix smaller than 2 and bigger than 36. What is impossible.

What you need is radix smaller than 2 or bigger than 36. So you can't nest the conditions.

If you compile

Code: Select all

if(2 > 100 > 36) or if(2 > 20 > 36)
both say:

Code: Select all

warning 205: redundant code: constant expression is zero
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests