Java 百分比总数不正确

Java 百分比总数不正确,java,math,rounding,Java,Math,Rounding,我正在分发代币,但它们并不都是分发的。我有多个百分比,并获得该百分比的代币数量,但它们不等于总数 例如: int tokens = 50; double[] percentages = new double[] {0.3725, 0.219, 0.115, 0.2935}; int total = 0; for(double d : percentages){ int amount = (int) (tokens * d); total += amount; } 不过总数是4

我正在分发代币,但它们并不都是分发的。我有多个百分比,并获得该百分比的代币数量,但它们不等于总数

例如:

int tokens = 50;
double[] percentages = new double[] {0.3725, 0.219, 0.115, 0.2935};

int total = 0;
for(double d : percentages){
    int amount = (int) (tokens * d);
    total += amount;
}
不过总数是47。我还试着用数学把它圆起来

for(double d : percentages){
    double rounded = Math.round(d * 100); 
    int amount = (int) (tokens * (rounded / 100));
    total += amount;
}
总数是49


我似乎永远也得不到50分,它总是低于或高于50分。我想把这些代币尽可能均匀地分发出去。如果你能帮忙,请做

使用
double
total
。使用int会导致十进制信息丢失

  double total = 0;
  for(double d : percentages){
      double amount = (tokens * d);
      total += amount;
  }

您应该做的是将百分比按原来的方式进行四舍五入(强制转换为int)。然后看看你还剩下多少代币。这些数据应分配到离其真实值最远的情况

在每种情况下,错误都是:

double error = (percentage * tokens) - (int)(percentage * tokens);

按错误对您的案例进行排序,并将令牌授予错误最大的案例,直到您给出全部50个为止。

我不确定为什么这样做有效,但我将总代码更改为

total += income/1.025;

我认为这是可行的,因为虽然循环没有显示68岁的年龄,但它仍然会运行最后一次。所以你必须撤销退休的利率

尝试使用
BigDecimal
而不是
double
double
数据类型通常不太适合表示小数并对其进行算术运算。转换为int会导致逗号后的数字丢失!是的,好的,
int
在表示小数方面比
double
更糟糕。错过了!另一个提示:理解您正在使用的概念。不要盲目地写下一些源代码;理解java拥有这些基本类型意味着什么,以及它们之间的转换是如何工作的。当你说令牌时,这些离散的东西是你试图分配的,以尽可能接近百分比的吗?令牌通常是离散的东西,将计数转换为双倍并不能真正解决问题。@sidgate我知道,但我需要等到问题提出后10分钟才能接受。而且现在这还没有真正解决问题。需要给出标记,但有些人不能有半个标记,因此之前它们是整数。数量必须是整数,并且必须等于50,如果你能弄清楚为什么会这样,并解释清楚,那么这将有助于这个问题的未来读者。