找回密码
 点一下
查看: 1600|回复: 8

任意进制数字转换函数

[复制链接]
发表于 2013-2-20 23:28:24 | 显示全部楼层 |阅读模式
本帖最后由 疯人¢衰人 于 2013-2-22 14:41 编辑

有人求进制转换函数,于是写了一个。
函数如下:
[codes=galaxy]
const string gv_NumbersSystemConversion = "NumbersSystemConversion";
const string gv_NumbersSystemConversionString = "String";
const string gv_NumbersSystemConversionNumber = "Number";
void Func_NumbersSystemConversionInit()
{
    //Int To String
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "0", "0");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "1", "1");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "2", "2");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "3", "3");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "4", "4");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "5", "5");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "6", "6");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "7", "7");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "8", "8");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "9", "9");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "10", "A");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "11", "B");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "12", "C");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "13", "D");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "14", "E");
    DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "15", "F");
   
    //String To Int
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "0", 0);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "1", 1);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "2", 2);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "3", 3);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "4", 4);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "5", 5);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "6", 6);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "7", 7);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "8", 8);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "9", 9);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "A", 10);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "B", 11);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "C", 12);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "D", 13);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "E", 14);
    DataTableSetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + "F", 15);
    //Add Others If Need
}
int Func_NumbersSystemConversionFromAToInt(int lp_A, string lp_S)
{
    int lv_I = 0;
    int lv_J = 0;
    int [2] lv_TempInt;
    int lv_StringLength = StringLength(lp_S);
   
    lv_TempInt[1] = 0;
   
    while (lv_I < lv_StringLength)
    {
        lv_I += 1;
        lv_J = lv_I;
        lv_TempInt[0] = 1;
        while (lv_J < lv_StringLength)
        {
            lv_TempInt[0] *= lp_A;
            lv_J += 1;
        }
        lv_TempInt[1] += (DataTableGetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + StringSub(lp_S, lv_I, lv_I)) * lv_TempInt[0]);
    }
    return lv_TempInt[1];
}
string Func_NumbersSystemConversionFromIntToB(int lp_B, int lp_S)
{
    string lv_TempString = "";
    if (lp_S == 0)
    {
        return DataTableGetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "0");
    }
   
    while (lp_S != 0)
    {
        lv_TempString = DataTableGetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + IntToString(ModI(lp_S, lp_B))) + lv_TempString;
        lp_S /= lp_B;
    }
    return lv_TempString;
}
string Func_NumbersSystemConversionFromAToB(int lp_A, int lp_B, string lp_S)
{
    return Func_NumbersSystemConversionFromIntToB(lp_B, Func_NumbersSystemConversionFromAToInt(lp_A, lp_S));
}
[/codes]

说明:
    1、函数使用前摇执行一次初始化函数Func_NumbersSystemConversionInit(),这个可以在SE的自定义脚本的初始化函数栏填入Func_NumbersSystemConversionInit来自动运行。
    2、输入输出的每位对应字符统一且任意自定义。具体方法参照Func_NumbersSystemConversionInit()函数。这个需要一一对应(数字到字符,字符到数字要相互对应。且每位字符不同)
    3、预定义的字符种类数要大于等于游戏中可能的最大进制数。如上面的脚本中,只定义了0~F共16个字符,那么可以转换的进制就是2~16间任意转换,但不支持17进制。
    4、Func_NumbersSystemConversionFromAToB为转换函数,参数中lp_A为输入进制,lp_B为输出进制,lp_S为输入数字(字符串类型),函数输出为字符串类型。
    5、如果要将正常的10进制整数转换成为其他进制的数,可以将整数转换成为字符串,在调用函数转换,这时参数lp_A为10.
    6、此函数不支持小数。不支持负数。没有效验输入内容是否符合进制(每位字符代表的数都小于进制,反例为输入进制为2,输入数字为22).
    7、附件函数的测试地图,默认为16进制转换为2进制,若想测试其他进制间转换,可以修改对战初始化触发的自定义脚本的内容。TriggerDebugOutput(1, StringToText(Func_NumbersSystemConversionFromAToB(16, 2, EventChatMessage(false))), true);中16和2根据需要进行修改。测试方法是直接输入想要测试的数字。

修改说明:因为Pow函数的有效范围比整数范围小很多(或者是fixed的有效数位的问题),所以第一个版本不支持大数字计算。于是做了第二个版本,目前版本的有效范围是0~2^31。也就是一个整数的非负部分。令拆分成为了两个函数。int Func_NumbersSystemConversionFromAToInt(int lp_A, string lp_S)用于将字符串类型的任意进制字符串数转换成为10进制整数,string Func_NumbersSystemConversionFromIntToB(int lp_B, int lp_S)则相反,用于将字符串类型的10进制字符串数转换成为任意进制整数

test.SC2Map

10.16 KB, 下载次数: 23

附件已经更新

 楼主| 发表于 2013-2-20 23:40:16 | 显示全部楼层
其实转换函数完全可以分成两个部分
[codes=galaxy]
    while (lv_I < lv_StringLength)
    {
        lv_I += 1;
        lv_TempInt += (DataTableGetInt(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionNumber + StringSub(lp_S, lv_I, lv_I)) * FixedToInt(Pow(lp_A, lv_StringLength - lv_I)));
    }
[/codes]
这部分是将输入的内容转换为10进制整数

[codes=galaxy]
    if (lv_TempInt == 0)
    {
        return DataTableGetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + "0");
    }
   
    while (lv_TempInt != 0)
    {
        lv_TempString = DataTableGetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString + IntToString(ModI(lv_TempInt, lp_B))) + lv_TempString;
        lv_TempInt /= lp_B;
    }
[/codes]

这部分是将10进制整数转换成指定进制的字符串数

有需要的童鞋可以自行封装成为函数。
回复

使用道具 举报

发表于 2013-2-20 23:54:11 | 显示全部楼层
恩,支持基础函数的制作。
回复

使用道具 举报

发表于 2013-2-22 08:32:25 | 显示全部楼层
顶起!这正是我 苦苦追寻的!
回复

使用道具 举报

发表于 2013-2-22 09:19:34 | 显示全部楼层
好像数值超过千万 就转不出来了?
我测试的 10->16
回复

使用道具 举报

 楼主| 发表于 2013-2-22 14:41:34 | 显示全部楼层
spjhot 发表于 2013-2-22 09:19
好像数值超过千万 就转不出来了?
我测试的 10->16

更新了
回复

使用道具 举报

发表于 2013-2-26 09:21:20 | 显示全部楼层
略加修改 可否实现 32进制 甚至更高 的 转换呢?加几条:
DataTableSetString(true, gv_NumbersSystemConversion + gv_NumbersSystemConversionString +? ?
这样的指令?
回复

使用道具 举报

 楼主| 发表于 2013-2-26 10:39:07 | 显示全部楼层
spjhot 发表于 2013-2-26 09:21
略加修改 可否实现 32进制 甚至更高 的 转换呢?加几条:
DataTableSetString(true, gv_NumbersSystemCon ...

对,就是设置好每一位的符号即可
不重复
回复

使用道具 举报

 楼主| 发表于 2013-2-26 10:39:09 | 显示全部楼层
spjhot 发表于 2013-2-26 09:21
略加修改 可否实现 32进制 甚至更高 的 转换呢?加几条:
DataTableSetString(true, gv_NumbersSystemCon ...

对,就是设置好每一位的符号即可
不重复
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-5-4 12:56 , Processed in 0.247321 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表