C# 对于c中的正数,强制转换为Int返回的值与FloorToInt不同#

C# 对于c中的正数,强制转换为Int返回的值与FloorToInt不同#,c#,casting,floor,C#,Casting,Floor,[编辑]我重写了评论中提到的整个示例 float value = 0.52631580f; float sum = 0; for (int i = 0; i < 10; i++) { float division = sum / value; int result = (int)division; Console.WriteLine(division.ToString("0.00000"

[编辑]我重写了评论中提到的整个示例

    float value = 0.52631580f;

    float sum = 0;
    for (int i = 0; i < 10; i++)
    {
        float division = sum / value;
        int result = (int)division;

        Console.WriteLine(division.ToString("0.00000") + " - " + result.ToString("0.00000"));
        sum += value;
    }
float值=0.52631580f;
浮点数和=0;
对于(int i=0;i<10;i++)
{
浮点除法=和/值;
int结果=(int)除法;
Console.WriteLine(division.ToString(“0.00000”)+“-”+result.ToString(“0.00000”));
总和+=数值;
}
结果并非预期的结果:

0,00000 - 0,00000
1,00000 - 1,00000
2,00000 - 2,00000
3,00000 - 3,00000
4,00000 - 4,00000
5,00000 - 5,00000
6,00000 - 5,00000 <---- It should be 6
7,00000 - 7,00000
000000-000000
1,00000 - 1,00000
2,00000 - 2,00000
3,00000 - 3,00000
4,00000 - 4,00000
5,00000 - 5,00000

600000-500000代码是正确的。并且符合标准。我将
WriteLine
行更改为:

Console.WriteLine($"{sum:0.000} {value:0.000} {division:N18} - {result:0.00000}");
得到

2.105 0.526 4.000000000000000000 - 4.00000
2.632 0.526 5.000000000000000000 - 5.00000
3.158 0.526 5.999999523162841797 - 5.00000

3.684 0.526 6.999999523162841797 - 6.00000

4.211 0.526 7.999999046325683594 - 7.00000

4.737 0.526 8.999999046325683594 - 8.00000
舍入误差意味着除法结果不完全是6、7或8。仅用5位数字,我得到:

3.158 0.526 6.00000 - 5.00000

3.684 0.526 7.00000 - 6.00000

4.211 0.526 8.00000 - 7.00000

4.737 0.526 9.00000 - 8.00000
这不是关于C#如何截断或舍入,而是关于浮点数的格式。IEEE兼容的方法是在格式化时四舍五入到所需的精度

呸-有一瞬间,我真的忘记了我对浮子的了解

注:在.NETCore3中引入了另一个有趣的功能。在此之前,字符串格式停止生成15位的数字,这导致与接近但不完全等于整数的值混淆

从.NET Core 3开始,字符串格式化程序将发出足够的数字,以生成
最短的可循环字符串
。使用

Console.WriteLine($"{division} - {result}");
产生:

4 - 4

5 - 5

5.9999995 - 5

6.9999995 - 6

7.999999 - 7

8.999999 - 8
这就是为什么他们教我们在计算数学中永远不要比较浮点数是否相等,而只检查绝对差值是否低于阈值

在崩溃或无限循环后,我总是忘记并不得不重新发现的东西

PPS:舍入错误

产生小数位数是因为
浮点
没有足够的精度来存储
,而不进行舍入

使用
$“{sum}{division}-{result}”
并从
float
切换到
double
只生成一个带小数位数的结果:

3.1578948 6 - 6

3.6842105999999997 6.999999999999999 - 6

4.2105264 8 - 8

请注意,即使是
sum
也有舍入错误

只有
decimal
具有足够的精度来存储准确的结果并避免舍入错误:

2.63157900 5 - 5

3.15789480 6 - 6

3.68421060 7 - 7

4.21052640 8 - 8

4.73684220 9 - 9


代码是正确的。并且符合标准。我将
WriteLine
行更改为:

Console.WriteLine($"{sum:0.000} {value:0.000} {division:N18} - {result:0.00000}");
得到

2.105 0.526 4.000000000000000000 - 4.00000
2.632 0.526 5.000000000000000000 - 5.00000
3.158 0.526 5.999999523162841797 - 5.00000

3.684 0.526 6.999999523162841797 - 6.00000

4.211 0.526 7.999999046325683594 - 7.00000

4.737 0.526 8.999999046325683594 - 8.00000
舍入误差意味着除法结果不完全是6、7或8。仅用5位数字,我得到:

3.158 0.526 6.00000 - 5.00000

3.684 0.526 7.00000 - 6.00000

4.211 0.526 8.00000 - 7.00000

4.737 0.526 9.00000 - 8.00000
这不是关于C#如何截断或舍入,而是关于浮点数的格式。IEEE兼容的方法是在格式化时四舍五入到所需的精度

呸-有一瞬间,我真的忘记了我对浮子的了解

注:在.NETCore3中引入了另一个有趣的功能。在此之前,字符串格式停止生成15位的数字,这导致与接近但不完全等于整数的值混淆

从.NET Core 3开始,字符串格式化程序将发出足够的数字,以生成
最短的可循环字符串
。使用

Console.WriteLine($"{division} - {result}");
产生:

4 - 4

5 - 5

5.9999995 - 5

6.9999995 - 6

7.999999 - 7

8.999999 - 8
这就是为什么他们教我们在计算数学中永远不要比较浮点数是否相等,而只检查绝对差值是否低于阈值

在崩溃或无限循环后,我总是忘记并不得不重新发现的东西

PPS:舍入错误

产生小数位数是因为
浮点
没有足够的精度来存储
,而不进行舍入

使用
$“{sum}{division}-{result}”
并从
float
切换到
double
只生成一个带小数位数的结果:

3.1578948 6 - 6

3.6842105999999997 6.999999999999999 - 6

4.2105264 8 - 8

请注意,即使是
sum
也有舍入错误

只有
decimal
具有足够的精度来存储准确的结果并避免舍入错误:

2.63157900 5 - 5

3.15789480 6 - 6

3.68421060 7 - 7

4.21052640 8 - 8

4.73684220 9 - 9


我们是否必须猜测sampleSize.x是什么,或者转换、截断或舍入的值是什么?强制转换并不意味着截断。如果
posX
是一个
float
为什么要在第一次计算中将其强制转换为
float
?那么到
怎么可能呢?
答案是
这是标准的
。如果需要,可以指定不同的舍入规则,例如舍入为偶数、远离零、接近零。然而,在信号和图像处理应用中,舍入/截断本质上是噪声。甚至可以消除这种噪音。地板/天花板最大化IT使用
Console.WriteLine(division.ToString(“G16”))
在每次迭代中打印
division
的原始值。对于重复操作中的浮点精度,您应该会发现结果很有启发性@Jeroenmoster打赌你也考虑过.NETCore3的变化?在本例中,差异出现在6位数字处。我们是否必须猜测
sampleSize.x
是什么,或者转换、截断或舍入的值是什么?强制转换并不意味着截断。如果
posX
是一个
float
为什么要在第一次计算中将其强制转换为
float
?那么到
怎么可能呢?
答案是
这是标准的
。如果需要,可以指定不同的舍入规则,例如舍入为偶数、远离零、接近零。然而,在信号和图像处理应用中,舍入/截断本质上是噪声。甚至可以消除这种噪音。地板/天花板最大化IT使用
Console.WriteLine(division.ToString(“G16”))
在每次迭代中打印
division
的原始值。对于重复操作中的浮点精度,您应该会发现结果很有启发性@Jeroenmoster打赌你也考虑过.NETCore3的变化?在这种情况下,差异出现在6位数字处。