我有一个totalPoints的浮点数,它会被Timer自动增加,但是在totalPoints达到一定数量之后,它似乎不再增加。我没有任何限制,所以我不确定为什么会这样。
因此,当totalPoints达到“2097152”值时,它会停止增加。
这是我的代码的一部分:
public float totalPoins;
void AccumulatePoints()
{
timer += Time.deltaTime * miningPowerValue;
if (timer > 1f)
{
totalPoints += someValue;
timer = 0;
}
}
所以基本上它会根据 miningPowerValue 累积积分。如果它低,它将以较慢的速率累积,更高 - 更快。请帮忙。我很困惑。
答案 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
。
现在,假设您尝试通过1
将Foo += 1
添加到此值。该值将变为1,234,001
。但由于我们的浮点值只能存储4个最大的数字,因此忽略1。 1,234,000
是1,234,001
的足够近似值。即使您添加了1
一千次,也不会改变任何内容,因为每次添加时它都会被舍入。同时,直接添加1,000
实际上会产生影响。
这是您的代码中发生的事情,规模更大,以及Joseph Sible试图传达的内容。这也解释了为什么totalPoints += 0.5f
在0.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位精度。
我希望这有助于解释正在发生的事情。