C# 如何进行定点除法?
我得到了一个使用long的8字节定点数字,其常量分母为(1),您可以使用来执行计算: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) /
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 };
}
}