在C#中,它告诉我如何没有返回浮点数的“Math.Cos”函数。 double是你可以获得的唯一值,因此强迫你将它转换为浮点数。
像这样:
float val = (float)Math.Cos(someVal);
我需要使用浮动因为我在Direct3D中做了严格使用浮点数的东西。 浮点数在图形世界中更常见(因为它现在是),因为它们是32位。
C#中是否有任何功能可以使用,只需处理像C ++那样的浮点数?
我不想包装任何C ++的东西,因为这需要在XNA& Linux for OpenGL。
注意:如果代码没有将double转换为浮点数,那就太棒了。
答案 0 :(得分:6)
如果不进行深入的数学运算,您将无法编写自己的准确 Cos函数。以下是使用扩展方法的建议:
class Program
{
static void Main(string[] args)
{
float cos = Math.Cos(.25d).ToFloat();
Console.WriteLine("cos(.25d) = {0}", cos);
Console.ReadKey();
}
}
public static class MathExtensions
{
public static float ToFloat(this double value)
{
return (float)value;
}
}
这是使用Func<T, TResult>
并创建自己的MathF
静态类的另一种方式:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("cos(.25d) = {0}", MathF.Cos(.25d));
Console.WriteLine("sin(.25d) = {0}", MathF.Sin(.25d));
Console.ReadKey();
}
}
public static class MathF
{
public static Func<double, float> Cos = angleR => (float)Math.Cos(angleR);
public static Func<double, float> Sin = angleR => (float)Math.Sin(angleR);
}
正如其他人所指出的那样,由于zezba在他的测试代码中证实了Func代表会变慢(我不知道代表会慢得多)。最快的是直接投射浮动。中间地带是MathF静态类中的简单静态方法调用。
答案 1 :(得分:6)
从.NET Core 2.0(.NET Standard 2.1)(C#8.0)和更高版本开始,这可能是内置函数。
您可以仅将MathF
类与内置常量或可用于float
类型的函数一起使用。
示例:
float cos = MathF.Cos(MathF.PI);
有关更多信息,请参见documentation on MSDN有关MathF
类型的信息。
答案 2 :(得分:4)
我会创建一个MathCommonMethods类,其方法可以将所有常用的返回类型转换为leiu of double中的浮点数。从长远来看,这将为您节省一些打字。
只要存在一个将值作为float返回的现有函数,我就没有听说过。
如果精度对您的应用很重要,那么在施法时也应该小心,不要失去精确度。
答案 3 :(得分:4)
好的,所以我在阅读“dboarman”回复后运行了一些基准测试,看看哪种方法最快。可悲的是,如果没有使用严格的c#&amp; amp;最快的方法就是现场施法,所以因为我关心速度,因为它主要是因为游戏不符合旧的演员方法。
使用以下规范::
编译这些测试C# .NET 4.0
ConsoleApplication - Release - Optimized code - x64
4gb ram, 2.4ghz AMD_X2_DualCore 4600 CPU, running Windows7 Ultimate.
代码:
static void Main(string[] args)
{
//Start
Console.Write("Hit Enter to Start\n");
Console.ReadLine();
long num = 100;
long mil = 0;
float val = 0.01f;
Stopwatch startTime = new Stopwatch();
//Run
for(long i = 0; i != num; ++i)
{
startTime.Restart();
for(uint i2 = 0; i2 != 1000000; ++i2) val = (float)System.Math.Cos(val);// 48 Milliseconds
//for(uint i2 = 0; i2 != 1000000; ++i2) val = System.Math.Cos(val).ToFloat();// 53 Milliseconds
//for(uint i2 = 0; i2 != 1000000; ++i2) val = MathF2.Cos(val);// 59 Milliseconds
//for(uint i2 = 0; i2 != 1000000; ++i2) val = MathF.Cos(val);// 63 Milliseconds
startTime.Stop();
mil += startTime.ElapsedMilliseconds;
}
//End
mil /= num;
//Print
Console.Write("Milliseconds = "+mil.ToString());
Console.ReadLine();
}
以下是tests ::
的基础数学代码public static class MathF
{
public static Func<double, float> Cos = angleR => (float)System.Math.Cos(angleR);
public static Func<double, float> Sin = angleR => (float)System.Math.Sin(angleR);
}
public static class MathF2
{
public static float Cos(float pValue) {return (float)System.Math.Cos(pValue);}
}
public static class MathExtensions
{
public static float ToFloat(this double value)
{
return (float)value;
}
}
答案 4 :(得分:2)
如果你想避免强制转换,你需要一个不同的实现。如果您正在跨平台,您可以创建一个平台抽象层,您可以在其中根据平台放置不同的实现。这将有助于提高性能。如果perf不是问题(游戏就是这种情况),那么创建一个效用函数并执行转换就是一个很好的解决方案。