关于超级大数字的一个想法

还是一次无聊的时候玩游戏的时候得到的灵感,那个游戏里的伤害/血量上升的极快,基本每级可以增加10%~20%,还有到特定级别增加400%这样类型的天赋,几百几千级以后数字就变得极其可怕。这个游戏的处理是直接不用正常的数字来计数(如果用正常的数字估计内存也存不下),而是使用字母来表示数量级,比如1B=1000A,1C=1000B,以此类推。这样的话,的确可以解决超级大数字的问题,只要建立一个对象,提供每个级别的变量值,如:

    //A的变量值,如500A则a=500,a<1000
    //private int a;
    //B的变量值
    //private int b;
    ....
    //思考了一下,用数组存应该更加科学,从前往后分别存放A-Z(根据需要,游戏中还有AA-AZ等的数值)
    private int[] data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0 };
    //对应的值的单位
    private String[] dataName = { "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z" };

然后提供显示当前数值(根据需要从大往下选择非0的显示)和改变数值的方法(更改对应变量,1000进制,加减乘除根据需要分别编写,此处只编写加法。减法类似加法;乘法复杂一些,需要单位角标相加;除法更复杂,未推导,有兴趣的可以自行推导一下。没有很精确的需求的话可以进行近似计算,即将最大的几位转成正常数字进行除法)

    //显示当前的值
    public String showData() {
        for (int i = data.length - 1; i >= 0; i--) {
            if (data[i] != 0) {
                if (i == 0) {
                    return data[i] + dataName[i];
                } else {
                    //根据需要选择显示的值,这里是最多保留一位小数
                    return formatNum(data[i] + (double) data[i - 1] / 1000)
                            + dataName[i];
                }
            }
        }
        return "0";
    }

    //两数相加
    public void addData(TestData td) {
        int[] addData = td.data;
        for (int i = 0; i < data.length; i++) {
            int origin = data[i];
            int add = addData[i];
            int result = add + origin;
            if (result < 1000) {
                data[i] = result;
            } else {
                // 此步可能导致数组越界,但是这种情况是数值大于设计最大数值造成的,应该算是设计上的问题
                data[i] = result - 1000;
                data[i + 1] += 1;
            }
        }
    }

    //增加某位的数值
    public void addData(int num, String name) {
        if (num > 1000) {
            throw new RuntimeException("数值不能大于1000");
        }
        int index = getNameIndex(name);
        if (index == -1) {
            throw new RuntimeException("未找到此数值对应名称,请确认");
        }
        int origin = data[index];
        int result = origin + num;
        if (result < 1000) {
            data[index] = result;
        } else {
            data[index] = result - 1000;
            data[index + 1] += 1;
        }
    }

基本的逻辑到此结束,理论上应该可以存储无限位数的数值,特定需求下可以作为一种参考方案使用。

附带例子中的工具方法:

    private int getNameIndex(String name) {
        for (int i = 0; i < dataName.length; i++) {
            if (name.equals(dataName[i])) {
                return i;
            }
        }
        return -1;
    }

    private String formatNum(double num) {
        NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(1);
        nf.setRoundingMode(RoundingMode.HALF_UP);
        /*
         * 如果想输出的格式用逗号隔开,可以设置成true
         */
        nf.setGroupingUsed(false);
        return nf.format(num);

    }
展开阅读全文

没有更多推荐了,返回首页