C# 浮点数在X之后不会增加

C# 浮点数在X之后不会增加,c#,unity3d,C#,Unity3d,我有一个由计时器自动增加的totalPoints的浮动,但是当totalPoints达到一定的数值后,它似乎不再增加了。我没有设置任何限制,所以我不知道为什么会发生这种情况 因此,totalPoints在达到2097152值时停止增加 以下是我的部分代码: public float totalPoins; void AccumulatePoints() { timer += Time.deltaTime * miningPowerValue; if (timer > 1f

我有一个由计时器自动增加的totalPoints的浮动,但是当totalPoints达到一定的数值后,它似乎不再增加了。我没有设置任何限制,所以我不知道为什么会发生这种情况

因此,totalPoints在达到2097152值时停止增加

以下是我的部分代码:

public float totalPoins;

void AccumulatePoints()
{

   timer += Time.deltaTime * miningPowerValue;

   if (timer > 1f)
   {    
      totalPoints += someValue;
      timer = 0;    
   }
}

所以基本上,它根据miningPowerValue累积点数。如果它很低,它将以较慢的速度积累,越高-越快。请帮忙。我很困惑。

浮点数越大,精确度越低。您遇到了这样一种情况,即它们足够大,以至于您试图添加的数量小于该大小的数字之间可能存在的最小差异。切换到double或其他更精确的选项。

以一种我不能简单通过评论的方式来扩展Joseph Sible的答案

A是一种指定浮点值的方法,在大多数编程语言中由IEEE 754规范定义。我们可以假设C的浮点值符合IEEE 754。浮点值被赋予一定数量的字节,它们在三个块中使用:正负号、x*10^y中的指数“y”和x*10^y中的值“x”。注意:这三个块的定义比这里所说的要复杂一些,但对于这个例子来说,它就足够了

换句话说,浮点值将值2000.00编码为正3,2。也就是说,正的2*10^3,或2*1000,或2000

这意味着浮点值可以表示非常大的值,但也意味着非常大的值往往会遇到错误。在某一点上,浮动需要开始删除其信息的末尾,以便获得其空间的最佳近似值

例如,假设我们试图使用一个非常小版本的浮点值来定义值1234567,它的x中只有4位数字的空间。1234567为阳性,6,1.234;1.234+10^6,计算结果为1.234*1000000,计算结果为1234000-后三位数字被删除,因为它们在估计中是最不重要的。假设我们将此值存储到变量Foo

现在,假设您尝试通过Foo+=1向该值添加1。该值将变为1234001。但是由于我们的浮点值只能存储4个最大的数字,所以1被忽略。1234000是1234001的一个足够好的近似值。即使你加了一千次,它也不会改变任何东西,因为每次你加的时候它都会被四舍五入。同时,事实上,直接添加1000会产生效果


这就是在你的代码中发生的事情,在更大的范围内,Joseph Sible试图传达的内容。这也解释了为什么当0.1136f不会-0.5大于0.1136时,totalPoints+=0.5f会起作用,这意味着0.1136在0.5之前不再有效。他建议你使用double,这更准确。A类似于单精度浮点值,但要大得多;也就是说,一个double可以比一个float存储更多的位,实际上是它的两倍,所以较小的数字不会那么容易丢失。这将解决您的问题,至少直到double需要再次删除小数字的时候

问题在于,您超出了仅为7位的“float”的精度

请看以下简单代码:

void Main()
{
    float f = 0.0f;
    float i = 0.1136f;

    int j = 0;
    while (f <= 3000000.0f)  //I arbitrarily chose 3 million here for illustration
    {
        f += i;

        //Only print after every 1000th iteration of the loop
        if (j % 1000 == 0)
        {
            Console.WriteLine(f);   
        }

        j++;
    }
}
然后,在一位之后,随着整数部分的增长,小数部分开始收缩:

9430.525
9543.807
9657.088
9770.369
9883.65
9996.932
10110.21
10223.49
10336.78
10450.06
10563.34
但随着值越来越高,它最终只输出以下内容:

999657.9
999782.9
999907.9
1000033
1000158
1000283
1000408
1000533
1000658
1000783
注意小数点后的部分是如何缩小的,而小数点前的部分是如何增大的?由于浮点数据类型只有7位精度,小数点后的最低有效位将被截断。另一方面,double具有16位精度


我希望这有助于解释发生了什么。

请查看更新的代码。我删除了0.15xxf值并替换为someValue,因为我的代码最初就是这样。不管怎么说,在那之前,我是某个人,值是0.1136f。例如,如果我加0.15f或更高的值,它可以正常工作。但在totalPoints达到2097152后,低于该数字或确切值的任何东西都不会加起来。困惑是吧?只是想让你知道,所以我们在同一页上。他说如果你使用int,你应该使用double而不是floatImagine。如果您试图将0.9添加到int,那么无论您添加了多少次,它都不会做任何事情,但是如果您将1.1添加到int,它将产生效果。这是同样的现象。约瑟夫,我决定在我自己的回答中详述你的答案和这些评论。我希望这不是在踩你的脚。@papi不是说你是瞎子……你得到了一个很可能解决你问题的答案,而不是去尝试,而是花了时间 谈论一些与约瑟夫的回答无关的事情。约瑟夫试图再次解释,但你驳斥了他说的话,声称问题是另外一回事,并以毫不犹豫的方式结束了它。谢谢你的努力。他没有尝试。他回答了你的问题。几个小时后,您仍然没有尝试此解决方案。我不明白将浮点转换为双精度或谷歌浮点精度需要多少能量
999657.9
999782.9
999907.9
1000033
1000158
1000283
1000408
1000533
1000658
1000783