还是一次无聊的时候玩游戏的时候得到的灵感,那个游戏里的伤害/血量上升的极快,基本每级可以增加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);
}