数据类型溢出

  在开发游戏的过程中遇到了成就统计溢出的问题,情况是统计获取金币的时候,对于一个玩家来说获取金币是无上限的,但是在程序里面使用的是Integer类型,所以会存在上限,一旦超过Integer上限,就会报错.

 public void addNum(int num){
        totalNum += num;
 }

这样的代码很明显到了后期,玩家金币数目获取过多就会报错.

我采用了比较折中的办法:

 public boolean addNum(int num){
        if((long)totalNum + (long)num > Integer.MAX_VALUE){
            return false;
        }
        totalNum += num;
        return true;
    }

虽然这样能够完成需求,单仍有很多问题,比如传入值小于0,线程安全等等问题.后来经过前辈提点,又修改了一个版本:

public int addNum(int vi) {
        synchronized (this) {//同步
            if (vi > 0) {
                if (Integer.MAX_VALUE - vi < value) {
                    value = Integer.MAX_VALUE;
                } else {
                    value += vi;
                }
            } else if (vi < 0) {
                if (Integer.MIN_VALUE - vi > value) {
                    value = Integer.MIN_VALUE;
                } else {
                    value += vi;
                }
            }
            value = value < 0 ? 0 : value;
            return value;
        }
    }

这样,就可以完成成就的统计并且不会溢出.但仍然有问题,关于经验使用的是Long计数,所以我需要在写一个传参为Long的方法,并不利于拓展,所以我修订了一下.

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;


/**
 * 修订版本
 *
 * @author JasonHung
 * @param <T>
 */
public class AmotNumber<T extends Number> implements Serializable, Cloneable {


    private AmotNumber() throws Exception {
        throw new Exception("不提供无参的构造方法");
    }


    private volatile T t;//某一类统计的具体数目


    private String typeName;//传入参数的具体类型,即泛型的具体类型


    public AmotNumber(T value) throws Exception {
        if (typeName == null || "".equals(typeName)) {
            getTrueType(value);
            switch (typeName) {
                case "java.lang.Integer":
                    Integer vi = (Integer) value;
                    Integer i = t == null ? 0 : (Integer) t;
                    i += vi;
                    t = (T) i;
                    break;
                case "java.lang.Double":
                    Double vd = (Double) value;
                    Double d = t == null ? 0 : (Double) t;
                    d += vd;
                    t = (T) d;
                    break;
                case "java.lang.Long":
                    Long vl = (Long) value;
                    Long l = t == null ? 0 : (Long) t;
                    l += vl;
                    t = (T) l;
                    break;
                case "java.lang.Float":
                    Float vf = (Float) value;
                    Float f = t == null ? 0 : (Float) t;
                    f += vf;
                    t = (T) f;
                    break;
                default:
                    throw new Exception("数据类型错误");
            }
        }
    }


    /**
     *
     * @param vi 传入的变值
     * @return
     * @throws Exception
     */
    public T addNum(T vi) throws Exception {
        synchronized (this) {//同步
            switch (typeName) {
                case "java.lang.Integer":
                    Integer i = t == null ? 0 : (Integer) t;
                    Integer v = (Integer) vi;
                    if (v > 0) {
                        if (Integer.MAX_VALUE - v < i) {
                            i = Integer.MAX_VALUE;
                        } else {
                            i += v;
                        }
                    } else if (v < 0) {
                        if (Integer.MIN_VALUE - v > i) {
                            i = Integer.MIN_VALUE;
                        } else {
                            i += v;
                        }
                    }
                    i = i < 0 ? 0 : i;
                    t = (T) i;
                    return t;
                case "java.lang.Long":
                    Long l = t == null ? 0 : (Long) t;
                    Long vl = (Long) vi;
                    if (vl > 0) {
                        if (Long.MAX_VALUE - vl < l) {
                            l = Long.MAX_VALUE;
                        } else {
                            l += vl;
                        }
                    } else if (vl < 0) {
                        if (Long.MIN_VALUE - vl > l) {
                            l = Long.MIN_VALUE;
                        } else {
                            l += vl;
                        }
                    }
                    l = l < 0 ? 0 : l;
                    t = (T) l;
                    return t;
                case "java.lang.Double":
                    Double d = t == null ? 0 : (Double) t;
                    Double vd = (Double) vi;
                    if (vd > 0) {
                        if (Double.MAX_VALUE - vd < d) {
                            d = Double.MAX_VALUE;
                        } else {
                            d += vd;
                        }
                    } else if (vd < 0) {
                        if (Double.MIN_VALUE - vd > d) {
                            d = Double.MIN_VALUE;
                        } else {
                            d += vd;
                        }
                    }
                    d = d < 0 ? 0 : d;
                    t = (T) d;
                    return t;
                case "java.lang.Float":
                    Float f = t == null ? 0 : (Float) t;
                    Float vf = (Float) vi;
                    if (vf > 0) {
                        if (Float.MAX_VALUE - vf < f) {
                            f = Float.MAX_VALUE;
                        } else {
                            f += vf;
                        }
                    } else if (vf < 0) {
                        if (Float.MIN_VALUE - vf > f) {
                            f = Float.MIN_VALUE;
                        } else {
                            f += vf;
                        }
                    }
                    f = f < 0 ? 0 : f;
                    t = (T) f;
                    return t;
                default:
                    throw new Exception("数据类型错误");
            }
        }
    }


    private void getTrueType(T value) {
        typeName = value.getClass().getTypeName();
    }


    public T getT() {
        return t;
    }


    public void setT(T t) {
        this.t = t;
    }


    public static void main(String[] args) throws Exception {
        AmotNumber<Double> a = new AmotNumber<>(1.0);
        a.addNum(2.0);
        Map<String, AmotNumber> as = new HashMap<>();
        as.put("d", a);
        AmotNumber<Double> get = as.get("d");
        get.addNum(100.0);
        get.addNum(10000.0);
        Number t1 = get.getT();
        System.out.println("i=" + t1);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值