"System.Math.Cos"可以返回(浮点)吗?

zez*_*000 14 .net c# math floating-point double

在C#中,它告诉我如何没有返回浮点数的"Math.Cos"函数.双精度是你可以获得的唯一值,因此强迫你将它投射到浮点数.像这样:
float val = (float)Math.Cos(someVal);

我需要使用浮点数,因为我在Direct3D中做了严格使用浮点数的东西.浮点数在图形世界中更常见(因为它现在是),因为它们是32位.

C#中是否有任何功能我可以使用它只是简单地处理浮点数,如C++可以做?

我不想包装任何C++的东西,因为这需要在XNA和Linux上运行OpenGL.

注意:如果代码没有将double转换为float,那将会很不错.

pic*_*ino 11

从 .NET Core 2.0 (.NET Standard 2.1) (C# 8.0) 开始,这可能是内置函数。

您可以只使用MathF具有内置常量的类或使用float类型的函数。

例子:

float cos = MathF.Cos(MathF.PI);
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅MSDN 上有关MathF类型的文档


IAb*_*act 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是使用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);
}
Run Code Online (Sandbox Code Playgroud)

正如其他人所指出的那样,由于zezba在他的测试代码中证实了Func代表会变慢(我不知道代表会慢得多).最快的是直接投射浮动.中间地带是MathF静态类中的简单静态方法调用.

  • 我不喜欢你的'MathF`的实现.定义`MathF`类的想法很好.但是在这里使用代表是愚蠢的(你的甚至不是只读字段).代表们只是在这里丢弃性能并使代码更难理解,因为例如文档将它们列为静态字段而不是静态方法.而且我认为函数应该使用float而不是double.`float Cos(float angle){return(float)Math.Cos(angle);}` (7认同)
  • 你为什么要写`static Func <double,float> Cos = angleR => ...`而不是`static float Cos(double angleR){...}`? (5认同)
  • Cos()不是转换为单精度扩展函数的好名称. (2认同)

zez*_*000 5

好的,所以我运行了一些基准测试,以查看阅读“ dboarman”回复后最快的方法。遗憾的是,如果不使用严格的c#进行强制转换,就无法做到这一点,而最快的方法就是直接进行强制转换,因为我关心速度,因为它主要用于游戏,因此不宜使用旧的强制转换方法。

这些测试是使用以下规范进行编译的:

C# .NET 4.0
ConsoleApplication - Release - Optimized code - x64
4gb ram, 2.4ghz AMD_X2_DualCore 4600 CPU, running Windows7 Ultimate.
Run Code Online (Sandbox Code Playgroud)

码:

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();
}
Run Code Online (Sandbox Code Playgroud)

这是测试的基本数学代码:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)