float 到 int cast 是仅接收整数的最佳解决方案吗?

Is the float to int cast the best solution to receive only integer number?

提问人:Matthew Strumiłło 提问时间:6/22/2020 更新时间:6/22/2020 访问量:306

问:

我不在乎精度。我只想在这个例子中使用最优化的代码。 例如:

  • 我通过将一个 int 类型除以一个浮点类型来计算一个刻度数,这样我就会收到一个浮点数。但实际上我只想要整数部分,所以我将其转换为 int 类型。
  • 但是在进一步的计算中,我需要这个数字是浮点数。所以我需要再次铸造它。

问题是:这是最好的方法吗?有没有一种方法可以在不强制转换和创建新变量的情况下修剪这个特定的“浮点”变量?

我将其标记为特定于语言,因为我很好奇其他语言是否也 c# 也会有某种方法。问题的另一部分是我真的不知道铸造在这里做什么,我还没有找到一个好的解释。

C# 强制转换 浮点 语言无关

评论

0赞 Athul Raj 6/22/2020
您需要值作为整数类型还是只需要整数值?Math.Floor() 和 Math.Ceil() 会将数字四舍五入为整数,但结果时间仍为浮点数/双精度
0赞 TheGeneral 6/22/2020
经过基准测试并返回浮动,它们在性能方面基本上非常接近,以至于无法区分,请选择您喜欢的castMath.Floor
0赞 Matthew Strumiłło 6/22/2020
所以我想我会留在演员阵容中。用于基准测试的 ty
0赞 TheGeneral 6/22/2020
@MatthewStrumi,我的第一个基准测试遇到了一些问题,但是我已经更新了结果。无论如何,祝你好运
0赞 chux - Reinstate Monica 6/23/2020
“通过将一个 int 类型除以一个浮点类型” --> 这两个值都是负数?

答:

2赞 Eric Postpischil 6/22/2020 #1

C# 提供 Math.Round 以舍入到最接近的整数,并提供 Math.Truncate 以取整数部分(向零舍入)。

我不在乎精度。

如果您不关心精度,请使用零而不是数字。这提供了极快的结果,但没有精度。

0赞 Vivek Nuna 6/22/2020 #2

您可以使用 ,但它会返回 。double d = Math.Floor(a / b);double

1赞 TheGeneral 6/22/2020 #3

一些基准

|   Method |           Job |       Runtime |      Mean |     Error |    StdDev | Ratio |
|--------- |-------------- |-------------- |----------:|----------:|----------:|------:|
|     Cast |    .NET 4.7.2 |    .NET 4.7.2 |  6.856 ms | 0.0858 ms | 0.0717 ms |  1.00 |
|     Cast | .NET Core 3.1 | .NET Core 3.1 |  6.799 ms | 0.0303 ms | 0.0269 ms |  0.99 |
|          |               |               |           |           |           |       |
|    Floor |    .NET 4.7.2 |    .NET 4.7.2 | 17.084 ms | 0.0708 ms | 0.0627 ms |  1.00 |
|    Floor | .NET Core 3.1 | .NET Core 3.1 | 22.654 ms | 0.0116 ms | 0.0091 ms |  1.33 |
|          |               |               |           |           |           |       |
| Truncate |    .NET 4.7.2 |    .NET 4.7.2 | 32.749 ms | 0.0411 ms | 0.0343 ms |  1.00 |
| Truncate | .NET Core 3.1 | .NET Core 3.1 | 32.803 ms | 0.0878 ms | 0.0821 ms |  1.00 |

测试

请注意,这不是世界上最经过深思熟虑的测试,但它至少会给出一个基本的比较

[SimpleJob(RuntimeMoniker.Net472, baseline: true)]
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
public class Test
{

   private float[] _input;
   private float[] _result;

   public Test()
   {
      var rand = new Random(24);
      _input = Enumerable.Range(0, 10000000).Select(x => (float)rand.NextDouble()).ToArray();
      _result = new float[10000000];

   }

   [Benchmark]
   public void Cast()
   {
      for (int i = 0; i < _input.Length; i++)
         _result[i] = (float)_input[i];
   }

   [Benchmark]
   public void Floor()
   {
      for (int i = 0; i < _input.Length; i++)
         _result[i] = (float)Math.Floor(_input[i]);
   }

   [Benchmark]
   public void Truncate()
   {
      for (int i = 0; i < _input.Length; i++)
         _result[i] = (float)Math.Truncate(_input[i]);
   }
}