【问题标题】:Complex numbers with decimal precision具有小数精度的复数
【发布时间】:2013-10-26 23:20:09
【问题描述】:

我正在使用 Math.Net Numerics 及其功能:

Transform.FourierForward(samples1, FourierOptions.Matlab);

samples1 必须是复杂结构,我使用的是复杂结构。但在这一点上我有一个问题。因为这个 Complex 结构正在使用 "double" 。我想处理十进制数。精度对我来说很重要。我怎么解决这个问题?

【问题讨论】:

    标签: c# precision


    【解决方案1】:

    你可以将双精度转换为十进制

    正如其他答案所建议的那样,使用 Math.Round() 并为其提供所需的精度,或使用 ToString() 并将其拆分为“。”或 ',' 取决于特定语言环境中 'dot' 的表示形式...

    【讨论】:

      【解决方案2】:

      您可以编写自己的复杂十进制结构。我这样做的方法是查看 System.Numerics.Complex - 构造并复制定义,以便您具有相同的功能和命名。如果您不需要某些函数,可以省略它们,例如三角函数、转换运算符,甚至是极坐标函数。

      我在下面的代码中实现了一些功能。请注意,您可能想要添加接口,并且可能需要对功能进行一些输入检查。

      public struct DecComplex
      {
      // Member variables.
      private decimal real;
      private decimal imaginary;
      
      
      // Read-only properties.
      public decimal Real { get { return real; } }
      public decimal Imaginary { get { return imaginary; } }
      
      
      // Constructors.
      public DecComplex(decimal real, decimal imaginary)
      {
        this.real = real;
        this.imaginary = imaginary;
      }
      
      public DecComplex(double real, double imaginary)
      {
        this.real = (decimal)real;
        this.imaginary = (decimal)imaginary;
      }
      
      
      // Arithmetic operators.
      public static DecComplex operator -(DecComplex value)
      {
        return new DecComplex(-value.real, -value.imaginary);
      }
      
      public static DecComplex operator +(DecComplex left, DecComplex right)
      {
        return new DecComplex(left.real + right.real, left.imaginary + right.imaginary);
      }
      
      public static DecComplex operator -(DecComplex left, DecComplex right)
      {
        return new DecComplex(left.real - right.real, left.imaginary - right.imaginary);
      }
      
      public static DecComplex operator *(DecComplex left, DecComplex right)
      {
        return new DecComplex(left.real * right.real - left.imaginary * right.imaginary, left.real * right.imaginary + left.imaginary * right.real);
      }
      
      public static DecComplex operator /(DecComplex left, DecComplex right)
      {
        var denominator = right.real * right.real + right.imaginary * right.imaginary;
        var real = (left.real / denominator * right.real + left.imaginary / denominator * right.imaginary);
        var imaginary = (left.imaginary / denominator * right.real - left.real / denominator * right.imaginary);
        return new DecComplex(real, imaginary);
      }
      
      public static DecComplex operator /(decimal left, DecComplex right)
      {
        var denominator = right.real * right.real + right.imaginary * right.imaginary;
        var real = left * right.real / denominator;
        var imaginary = - left * right.imaginary / denominator;
        return new DecComplex(real, imaginary);
      }
      
      
      // Conversion operators.
      public static explicit operator System.Numerics.Complex(DecComplex value)
      {
        return new System.Numerics.Complex((double)value.Real, (double)value.Imaginary);
      }
      
      
      // Methods.
      public static decimal Abs(DecComplex value)
      {
        return Sqrt(value.real * value.real + value.imaginary * value.imaginary);
      }
      
      public static DecComplex Pow(DecComplex value, int exponent)
      {
        if (exponent == 0)
          return new DecComplex(1.0, 0.0);
      
        var result = value;
        for (var i = 1; i < exponent; i++)
        {
          result = result * value;
        }
      
        if (exponent < 0)
          return 1.0M / result;
        else
          return result;
      }
      
      public override string ToString()
      {
        return string.Format("({0}; {1})", this.real, this.imaginary);
      }
      
      
      // Sqrt-Method for the decimal class (by SLenik, http://stackoverflow.com/a/6755197/4469336).
      public static decimal Sqrt(decimal x, decimal epsilon = 0.0M)
      {
        if (x < 0) throw new OverflowException("Cannot calculate square root from a negative number");
      
        decimal current = (decimal)Math.Sqrt((double)x), previous;
        do
        {
          previous = current;
          if (previous == 0.0M) return 0;
          current = (previous + x / previous) / 2;
        }
        while (Math.Abs(previous - current) > epsilon);
        return current;
      }
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-04
        • 2022-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多