我使用longs得到一个8字节的定点数,其恒定分母为(1 <&lt;&lt;&lt;&lt;&lt;&lt;&lt; 24)。如何分割两个Fixed8值?由于我使用C#,我不能简单地转换为更大的整数。或者我在语言上想得太多了?
感谢。
public struct Fixed8
{
private long _numerator;
public const long DENOMINATOR = 1 << 24;
}
答案 0 :(得分:1)
您可以使用BigInteger Structure执行计算:
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 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
答案 1 :(得分:1)
这是一种将所有计算保持在long
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 };
}
}
答案 2 :(得分:0)
public long Division()
{
long result = _numerator / DENOMINATOR;
return result;
}
答案 3 :(得分:0)
使用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) };
}