C# 中 frac 函数的最快实现

发布于 2024-09-06 00:26:09 字数 655 浏览 11 评论 0原文

我想在 C# 中实现一个 frac 函数(就像 hsl 中的函数一样 http://msdn.microsoft.com/en-us/library/bb509603%28VS.85%29.aspx),但由于它是针对处理器密集型应用程序,我希望可能的最佳版本。我正在使用类似的东西

public float Frac(float value)
{
   return value - (float)Math.Truncate(value);
}

,但我遇到了精度问题,例如对于 2.6f,它在单元测试中返回

预期:0.600000024f 但为:0.599999905f

我知道我可以将值转换为十进制,然后最后转换为float 以获得正确的结果,如下所示:

public float Frac(float value)
{
   return (float)((decimal)value - Decimal.Truncate((decimal)value));
}

但我想知道是否有更好的方法而不诉诸小数......

I would like to implement a frac function in C# (just like the one in hsl here http://msdn.microsoft.com/en-us/library/bb509603%28VS.85%29.aspx) but since it is for a very processor intensive application i would like the best version possible. I was using something like

public float Frac(float value)
{
   return value - (float)Math.Truncate(value);
}

but I'm having precision problems, for example for 2.6f it's returning in the unit test

Expected: 0.600000024f But was: 0.599999905f

I know that I can convert to decimal the value and then at the end convert to float to obtain the correct result something like this:

public float Frac(float value)
{
   return (float)((decimal)value - Decimal.Truncate((decimal)value));
}

But I wonder if there is a better way without resorting to decimals...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寄居人 2024-09-13 00:26:09

float(System.Single 的别名)仅精确到 7数字。无论如何,您不应该真正使用相等来比较浮点值。您应该检查它们是否在可容忍的范围内 - 例如,预期值和实际值之间的差异不超过 0.000001。

Assert.AreEqual(expected, actual, delta);

如果您使用 double 代替,您将精确到 15-16数字。

float (an alias for System.Single) is only precise to 7 digits. You shouldn't really compare floating point values using equality anyway. You should instead check that they are within a tolerable range - for example that the difference between the expected and actual values is not more than 0.000001.

Assert.AreEqual(expected, actual, delta);

If you use double instead, you will be precise to 15-16 digits.

老娘不死你永远是小三 2024-09-13 00:26:09

您将需要使用小数,如下所示:

public decimal Frac(decimal value) { return value - Math.Truncate(value); }

因此,当您超过 2.6m 时,您将始终得到 0.6

You are going to need to use decimals as in:

public decimal Frac(decimal value) { return value - Math.Truncate(value); }

So, when you pass 2.6m you will always get .6

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文