Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何进行定点除法?_C#_Fixed Point - Fatal编程技术网

C# 如何进行定点除法?

C# 如何进行定点除法?,c#,fixed-point,C#,Fixed Point,我得到了一个使用long的8字节定点数字,其常量分母为(1),您可以使用来执行计算: public static Fixed8 operator /(Fixed8 a, Fixed8 b) { Fixed8 result; result._numerator = (long)( new BigInteger(a._numerator) * new BigInteger(DENOMINATOR) /

我得到了一个使用long的8字节定点数字,其常量分母为(1),您可以使用来执行计算:

public static Fixed8 operator /(Fixed8 a, Fixed8 b)
{
    Fixed8 result;
    result._numerator = (long)( new BigInteger(a._numerator) *
                                new BigInteger(DENOMINATOR)  /
                                new BigInteger(b._numerator) );
    return result;
}
完整代码:

输出:

7. 1.69999998807907 4.11764705181122
使用
System.Numerics.BigInteger
是可以的。但在这种特定情况下,
System.Decimal
实际上具有足够的精度。因此,我的建议如下:

 public static Fixed8 operator /(Fixed8 a, Fixed8 b)
 {
   decimal resultNumerator = (decimal)a._numerator * DENOMINATOR / b._numerator;
   return new Fixed8 { _numerator = Convert.ToInt64(resultNumerator) };
 }

这里有一种方法可以让所有的计算都保持在
长的
s中。不过可能不会更快;我还没有测量过

public struct Fixed8
{
    public Fixed8(double value)
    {
        _numerator = (long)(value * DENOMINATOR);
    }

    private long _numerator;
    public const long DENOMINATOR = 1 << 24;

    public static Fixed8 operator /(Fixed8 a, Fixed8 b)
    {
        long remainder;
        long quotient = Math.DivRem(a._numerator, b._numerator, out remainder) * DENOMINATOR;

        long morePrecision = remainder * DENOMINATOR / b._numerator;

        return new Fixed8 { _numerator = quotient + morePrecision };
    }
}
公共结构已修复8
{
公共固定8(双值)
{
_分子=(长)(值*分母);
}
私人长分子;

public const long deminator=1你的意思是你想计算
a/b
其中
a
b
是两个
固定的8
值吗?对不起,我想这很清楚。是的。我脑子里有一个模糊的想法,如果我使用M32.N32,计算会更容易。尽管这可能需要四个separate计算。在回答问题之前,如果你不知道定点数字是什么,请先查找它们。它们不是分数。虽然这是一种可能性,但BigInteger本质上很慢。我希望除法速度很快。除非有什么数学诀窍在64位进行除法,否则你几乎只能使用BigInteger或你自己的工具一个更大的数据类型。可能问?可能会有帮助;可能会因为是一个编程问题而关闭该问题。当然,您必须重新表述该问题,因为您的实际问题与编程没有直接关系。本质上,您需要计算
((i*j)模2^64)/k)模2^64
得到与
(i*j)/k
相同的结果。首先分离符号可能会有帮助。难道(i*j)/k也必须是((i*j)/k)模2^64吗?并且说“仅正值”会起作用吗?目前使用这个方法;但可能不是最有效的方法。@NarftheMouse为什么你认为它不是“最有效”?您需要什么效率?您的应用程序是否花费了所有资源来划分
Fixed8
?对不起,应该澄清一下。这是我自己指定的练习。提高速度是练习的一部分。因为我从未参加过正式课程(在一些互联网教程网站之外),诸如此类的事情很重要。
public const long DENOMINATOR = 1 << 24;

private long _numerator;

public Fixed8(double value)
{
    _numerator = (long)(value * DENOMINATOR);
}

public static Fixed8 operator /(Fixed8 a, Fixed8 b)
{
    Fixed8 result;
    result._numerator = (long)( new BigInteger(a._numerator) * 
                                new BigInteger(DENOMINATOR)  / 
                                new BigInteger(b._numerator) );
    return result;
}

public static explicit operator double(Fixed8 a)
{
    return (double)a._numerator / (double)DENOMINATOR;
}

public override string ToString()
{
    return ((double)this).ToString();
}
var a = new Fixed8(7);
var b = new Fixed8(1.7);

Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(a / b);
7 1.69999998807907 4.11764705181122
 public static Fixed8 operator /(Fixed8 a, Fixed8 b)
 {
   decimal resultNumerator = (decimal)a._numerator * DENOMINATOR / b._numerator;
   return new Fixed8 { _numerator = Convert.ToInt64(resultNumerator) };
 }
public struct Fixed8
{
    public Fixed8(double value)
    {
        _numerator = (long)(value * DENOMINATOR);
    }

    private long _numerator;
    public const long DENOMINATOR = 1 << 24;

    public static Fixed8 operator /(Fixed8 a, Fixed8 b)
    {
        long remainder;
        long quotient = Math.DivRem(a._numerator, b._numerator, out remainder) * DENOMINATOR;

        long morePrecision = remainder * DENOMINATOR / b._numerator;

        return new Fixed8 { _numerator = quotient + morePrecision };
    }
}