我想计算直线的斜率。
public sealed class Point
{
public System.Numerics.BigInteger x = 0;
public System.Numerics.BigInteger y = 0;
public double CalculateSlope (Point point)
{
return ((point.Y - this.Y) / (point.X - this.X));
}
}
我知道的BigInteger返回除法结果加上其余但我不知道如何使用它获得双重一个DivRem功能。 我处理的数字是远远远远超出Int64.MaxValue的范围,其余本身可能是超出范围由传统的部门来计算。
编辑 :不知道是否有帮助,但我只用正整数处理(> = 1)。
重要提示 :我只需要精密几个小数点(5应该是对我来说已经足够了)。
该BigRational库有一个转换操作符将翻一番。
此外,请记住返回无穷大作为特殊情况下的垂直线,你会零异常得到鸿沟与您现有的代码。 也许最好只计算X1 - X2第一,并返回无穷大,如果是零,然后做分工,避免重复操作。
获得BigRational从Codeplex上。 其微软的一部分基类库 ,所以这是一个工作在进展.NET。 一旦你的,然后做一些事情,如:
System.Numerics.BigInteger x = GetDividend() ;
System.Numerics.BigInteger y = GetDivisor() ;
BigRational r = new BigRational( x , y ) ;
double value = (double) r ;
其必然溢/下溢/失去精度处理,当然,另一个问题。
既然你不能在BigRational库拖放到你的代码,显然,其他的办法是走出正确的算法书 ,并推出自己的...
最简单的办法,当然是的“滚动自己”在这里,因为有理数表示为两个整数之比(师),就是要抓住从BigRational类的显式转换到双操作和调整它来满足。 我花了大约15分钟。
关于我做出的唯一显著修饰是怎么当的结果为正或负零/无穷结果的标志设置。 当我在这,我把它转换成一个BigInteger
给你扩展方法:
public static class BigIntExtensions
{
public static double DivideAndReturnDouble( this BigInteger x , BigInteger y )
{
// The Double value type represents a double-precision 64-bit number with
// values ranging from -1.79769313486232e308 to +1.79769313486232e308
// values that do not fit into this range are returned as +/-Infinity
if (SafeCastToDouble(x) && SafeCastToDouble(y))
{
return (Double) x / (Double) y;
}
// kick it old-school and figure out the sign of the result
bool isNegativeResult = ( ( x.Sign < 0 && y.Sign > 0 ) || ( x.Sign > 0 && y.Sign < 0 ) ) ;
// scale the numerator to preseve the fraction part through the integer division
BigInteger denormalized = (x * s_bnDoublePrecision) / y ;
if ( denormalized.IsZero )
{
return isNegativeResult ? BitConverter.Int64BitsToDouble(unchecked((long)0x8000000000000000)) : 0d; // underflow to -+0
}
Double result = 0 ;
bool isDouble = false ;
int scale = DoubleMaxScale ;
while ( scale > 0 )
{
if (!isDouble)
{
if ( SafeCastToDouble(denormalized) )
{
result = (Double) denormalized;
isDouble = true;
}
else
{
denormalized = denormalized / 10 ;
}
}
result = result / 10 ;
scale-- ;
}
if (!isDouble)
{
return isNegativeResult ? Double.NegativeInfinity : Double.PositiveInfinity;
}
else
{
return result;
}
}
private const int DoubleMaxScale = 308 ;
private static readonly BigInteger s_bnDoublePrecision = BigInteger.Pow( 10 , DoubleMaxScale ) ;
private static readonly BigInteger s_bnDoubleMaxValue = (BigInteger) Double.MaxValue;
private static readonly BigInteger s_bnDoubleMinValue = (BigInteger) Double.MinValue;
private static bool SafeCastToDouble(BigInteger value)
{
return s_bnDoubleMinValue <= value && value <= s_bnDoubleMaxValue;
}
}
这不对付负,但希望给你一个开始。
double doubleMax = double.MaxValue;
BigInteger numerator = 120;
BigInteger denominator = 50;
if (denominator != 0)
{
Debug.WriteLine(numerator / denominator);
Debug.WriteLine(numerator % denominator);
BigInteger ansI = numerator / denominator;
if (ansI < (int)doubleMax)
{
double slope = (double)ansI + ((double)(numerator % denominator) / (double)denominator); ;
Debug.WriteLine(slope);
}
}