X号

时间:2018-03-18 02:49:28

标签: c# unity3d

我有一个totalPoints的浮点数,它会被Timer自动增加,但是在totalPoints达到一定数量之后,它似乎不再增加。我没有任何限制,所以我不确定为什么会这样。

因此,当totalPoints达到“2097152”值时,它会停止增加。

这是我的代码的一部分:

public float totalPoins;

void AccumulatePoints()
{

   timer += Time.deltaTime * miningPowerValue;

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

所以基本上它会根据 miningPowerValue 累积积分。如果它低,它将以较慢的速率累积,更高 - 更快。请帮忙。我很困惑。

3 个答案:

答案 0 :(得分:4)

随着浮点数变大,浮点数变得越来越精确。您遇到的情况是,它们足够大,以至于您尝试添加的数量小于该数量的数字之间的最小可能差异。切换到double或其他更精确的东西。

答案 1 :(得分:3)

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

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

换句话说,浮点值将编码值" 2,000.00" as" positive,3,2"。也就是说,正2 * 10 ^ 3,或2 * 1000,或2,000。

这意味着浮点值可以表示非常大的值,但这也意味着非常大的值往往会遇到错误。在某个时刻,花车需要开始"砍掉"信息的结尾,以便获得他们所拥有的空间的最佳近似值。

例如,假设我们尝试使用非常小的浮点值版本来定义值1,234,567,并且它的x中只有4位数的空格。 1,234,567将变为“正面,6,1.234&#34 ;;计算到1.234 + 10 ^ 6的{​​{1}} 1.234 * 1,000,000计算到1,234,000 - 后三位数被删除,因为它们是"最不重要的"为了估计的目的。假设我们将此值存储到变量Foo

现在,假设您尝试通过1Foo += 1添加到此值。该值将变为1,234,001。但由于我们的浮点值只能存储4个最大的数字,因此忽略1。 1,234,0001,234,001足够近似值。即使您添加了1一千次,也不会改变任何内容,因为每次添加时它都会被舍入。同时,直接添加1,000实际上会产生影响。

这是您的代码中发生的事情,规模更大,以及Joseph Sible试图传达的内容。这也解释了为什么totalPoints += 0.5f0.1136f不会 - 0.5的数字大于0.1136的情况下有效0.1136,这意味着0.5停止了重要&{34}} #34;在double之前。他建议您使用double更精确double-precision floating-point value类似于单精度浮点值,但相当大;也就是说,float可以存储比def cleanInput(question,retry=False): inputValue = input("\n\nOnly positive numbers can be entered, please re-enter the value.\n\n{}".format(question)) if retry else input(question) try: if float(inputValue) <= 0 : raise ValueError() else : return(float(inputValue)) except ValueError : return(cleanInput(question,retry=True)) willbefloat = cleanInput("Give me the number: ") 更多的比特(事实上大约是其两倍),因此较小的数字不会轻易丢失。这将解决你的问题,至少直到双重需要再次开始减少小数字的时候!

答案 2 :(得分:1)

问题在于你超过了'浮动'的精确度。这只是7位数。

请看以下简单代码:

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++;
    }
}

在此代码的开头,您将看到如下值:

0.1136
113.7148
227.3164
340.9067
454.4931
568.0796

然后,在一点之后,随着整数部分的增长,小数部分开始缩小:

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

请注意十进制后的部分如何收缩但是之前的部分会增加?由于float数据类型只有7位精度,因此小数点后的最低有效位将被截断。另一方面,double具有16位精度。

我希望这有助于解释正在发生的事情。