进行对包含整型变量的list进行操作造成计算错误 5C

问题很简单,可以复现。也可能是太久没接触代码的简单问题。
看了一个短视频,说人类的贫富差距28定律,用计算机随机可以发现是一样的。
想了一下觉得并不难实现,所以想要试一下。
思路是循环创建100个包含name和money字段的对象。
并把它们存进list
取随机坐标的两个对象实现一次money的随机数额的交易。
该交易是单向的,一方减少多少,另一方就增加多少。如果要被减少的一方已经是0,便不操作
代码如下:

function start() {

var objects=new Array();
for(var i=1;i<101;i++){
    var object=new Map()    ;
    object.set('name',i);
    object.set('money',10);
    objects.push(object)
}
    //这里是单纯为验证当前数组里money的总和是多少这里输出是正常的10000
var moneysxm=0;
for(var w=0;w<objects.length;w++){
    moneysxm+=objects[w].get('money')
}
console.log(moneysxm);

for(var z=0;z<$('#f').val();z++){
    //随机取两个数
    var demo1int=sum(0,99);
    var demo2int=sum(0,99);
    //获得随机数字对应的数组对象
    var demo1object=objects[demo1int];
    var demo2object=objects[demo2int];
    //获得对象1的金钱数额
    var demo1money=demo1object.get('money');
    //获得对象2的金钱数额
    var demo2money=demo2object.get('money');
    console.log(demo1object.get('name')+'##'+demo1money)
    console.log(demo2object.get('name')+'##'+demo2money)
    //当该对象金钱数额为0时不作为
            //如果两个对象是同一个时不作为
    if(demo1money!=0||demo1int!=demo2int){
        //获得符合该对象当前金钱范围内的随机支出数额
        var demo1zhichu=sum(1,demo1money);
        //获得对象1的剩余数额
        demo1money-=demo1zhichu;
        //将对象1剩余数额存入数组
        objects[demo1int].set('money',demo1money);
        //获得对象二获得数额后的总数额
        demo2money+=demo1zhichu;
        //将对象2获得数额后的总数额存入数组
        objects[demo2int].set('money',demo2money);

    }
    console.log(objects[demo1int].get('name')+'##'+objects[demo1int].get('money'));
    console.log(objects[demo1int].get('name')+'##'+objects[demo2int].get('money'));
}
var moneysxm=0;
for(var s=0;s<objects.length;s++){
    moneysxm+=objects[s].get('money')
}
console.log(moneysxm);
//排序
for(var o=0;o<objects.length;o++){
    for(var u=0;u<objects.length;u++){
        if(objects[o].get('money')<objects[u].get('money')){
            var g=objects[o];
            objects[o]=objects[u];
            objects[u]=g;
        }
    }
}
setobjects=objects;
console.log(setobjects);
moneysxm=0;
for(var q=0;q<setobjects.length;q++){
    moneysxm+=setobjects[q].get('money')
}
console.log(moneysxm);

}

function sum (m,n){
var num = Math.floor(Math.random()*(m - n) + n);
return num;
}

#f是一个输入框
输入的是循环次数
图片说明
但是问题这段逻辑感觉并没有什么问题,但是问题却出现了
当主要的对象随机交易这段循环走过之后,money的总量发生了变化,循环次数越多,出错概率越大,越离谱
图片说明

由于之前主要做的后端,之所以用js来试,是因为js不用jdk。但是之前调试前端时也总是出现各种各样的问题,最后我怀疑是又遇到了什么莫名其妙的前端都知道的潜在bug
所以决定用相同的逻辑再用java试一下。
java是强类型的,应该不会再出现这种事情了吧。但是显然,我错了。
public class test1234 {

public static void main(String[] args) {

    ArrayList<persion> arrayList = new ArrayList<persion>();

    //创建100个对象
    for(int i=1;i<101;i++){
        persion persion = new persion();
        persion.setName(String.valueOf(i));
        persion.setMoney(10);
        arrayList.add(persion);

    }

    for(int z=0;z<1000;z++){
        //随机取两个数
        int demo1int=sum(0,99);
        int demo2int=sum(0,99);
        //获得随机数字对应的数组对象
        persion demo1object=arrayList.get(demo1int);
        persion demo2object=arrayList.get(demo2int);
        //获得对象1的金钱数额
        int demo1money=demo1object.getMoney();
        //获得对象2的金钱数额
        int demo2money=demo2object.getMoney();
        //当该对象金钱数额为0时不作为
        if(demo1money!=0){
            //获得符合该对象当前金钱范围内的随机支出数额
            int demo1zhichu=sum(1,demo1money);
            //获得对象1的剩余数额
            demo1money-=demo1zhichu;
            //将对象1剩余数额存入数组
            demo1object.setMoney(demo1money);
            //获得对象二获得数额后的总数额
            demo2money+=demo1zhichu;
            //将对象2获得数额后的总数额存入数组
            demo2object.setMoney(demo2money);
        }
    }


        int moneysxm=0;
        for(int s=0;s<arrayList.size();s++){
            moneysxm+=arrayList.get(s).getMoney();
        }


    System.out.println(moneysxm);



}
![图片说明](https://img-ask.csdn.net/upload/202002/25/1582578602_162708.jpg)
java也输出了一些令人害怕的money总量
那么肯定是我犯了什么弱智错误了吧,可无论如何也不知道哪里错了,去网上查,大部分计算错误是由于浮点计算造成的,这个我遇到过,但是整型不涉及二进制的缺陷啊。另外我记得list循环不能对对象操作?好像有这个说法?忘了,

2个回答

哈哈哈,我也是够无聊的,还跟你验证这个!
下面的放到Z循环里面你会发问题

这是总额变化的输出结果 "本次支出方为21收款方为21支出为10当前计算次数57结果为1010"

            int moneysxm=0;
            for(int s=0;s<arrayList.size();s++){
                moneysxm+=arrayList.get(s).getMoney();
            }
            if(demo1money!=0){
            System.out.println("本次支出方为" + demo1object.getName() + "收款方为" + demo2object.getName() + "支出为" + demo1zhichu + "当前计算次数" + String.valueOf(z) + "结果为" + moneysxm);
            }
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐