public BigInteger Round() { BigRational r = this + new BigRational(BigInteger.One, new BigInteger(2)); if (r.Denominator == BigInteger.One) { if ((r.Numerator & BigInteger.One) != BigInteger.Zero) { return(r.Numerator - BigInteger.One); } else { return(r.Numerator); } } else { return(r.Floor()); } }
public float GetSingleValue(RoundingMode m) { if (this.IsZero) { return(0.0f); } Tuple <BigRational, int> normalized = Normalize(this); BigRational frac = normalized.Item1; int expt = normalized.Item2; expt += 127; int loops = 24; while (expt < 0 && loops > 0) { frac /= Two; expt += 1; loops -= 1; } if (expt <= 0) { expt = 0; frac /= Two; } if (expt > 254) { return((frac < Zero) ? float.NegativeInfinity : float.PositiveInfinity); } int bits = (frac * singleFractionScale).RoundingOp(m).GetInt32Value(OverflowBehavior.Saturate); if (bits < 0) { bits = (-bits) | unchecked ((int)0x80000000L); } bits &= unchecked ((int)0x807FFFFFL); bits |= expt << 23; return(BitConverter.ToSingle(BitConverter.GetBytes(bits), 0)); }
public double GetDoubleValue(RoundingMode m) { if (this.IsZero) { return(0.0); } Tuple <BigRational, int> normalized = Normalize(this); BigRational frac = normalized.Item1; int expt = normalized.Item2; expt += 1023; int loops = 53; while (expt < 0 && loops > 0) { frac /= Two; expt += 1; loops -= 1; } if (expt <= 0) { expt = 0; frac /= Two; } if (expt > 2046) { return((frac < Zero) ? double.NegativeInfinity : double.PositiveInfinity); } long bits = (frac * doubleFractionScale).RoundingOp(m).GetInt64Value(OverflowBehavior.Saturate); if (bits < 0) { bits = (-bits) | unchecked ((long)0x8000000000000000L); } bits &= unchecked ((long)0x800FFFFFFFFFFFFFL); bits |= (long)expt << 52; return(BitConverter.Int64BitsToDouble(bits)); }
public override ConvexHull Add(Vertex3 vt) { if (this.Line.Contains(vt)) { BigRational scaledPos = (vt - v1).ScaledLengthAlong(v2 - v1); if (scaledPos < BigRational.Zero) { return(new CH_LineSegment(vt, v2)); } else if (scaledPos > BigRational.One) { return(new CH_LineSegment(v1, vt)); } else { return(this); } } else { return(new CH_Polygon(new Vertex3[] { v1, v2, vt }.ToImmutableList())); } }
public override PointStatus GetPointStatus(Vertex3 vt) { if (v1 == vt || v2 == vt) { return(PointStatus.OnCorner); } else if (this.Line.Contains(vt)) { BigRational scaledPos = (vt - v1).ScaledLengthAlong(v2 - v1); if (scaledPos < BigRational.Zero || scaledPos > BigRational.One) { return(PointStatus.Outside); } else { return(PointStatus.OnEdge); } } else { return(PointStatus.Outside); } }
public static Vector3 Interpolate(BigRational x1, Vector3 y1, BigRational x2, Vector3 y2, BigRational x3) { return(y1 + (y2 - y1) * (x3 - x1) / (x2 - x1)); }
// (y3 - y1) (x3 - x1) // --------- = --------- // (y2 - y1) (y2 - y1) // (x3 - x1) // y3 = y1 + (y2 - y1) * --------- // (x2 - x1) public static BigRational Interpolate(BigRational x1, BigRational y1, BigRational x2, BigRational y2, BigRational x3) { return(y1 + (y2 - y1) * (x3 - x1) / (x2 - x1)); }
public Vertex3(BigRational x, BigRational y, BigRational z) { this.x = x; this.y = y; this.z = z; }
public Vertex2(BigRational x, BigRational y) { this.x = x; this.y = y; }
public static Vector2 operator *(BigInteger a, Vector2 b) { BigRational aa = new BigRational(a, BigInteger.One); return(new Vector2(aa * b.x, aa * b.y)); }
public static Vector2 operator *(Vector2 a, BigInteger b) { BigRational bb = new BigRational(b, BigInteger.One); return(new Vector2(a.x * bb, a.y * bb)); }
public Vector2(BigRational x, BigRational y) { this.x = x; this.y = y; }
public static Vector3 operator /(Vector3 a, BigInteger b) { BigRational bb = new BigRational(b, BigInteger.One); return(new Vector3(a.x / bb, a.y / bb, a.z / bb)); }
public static Tuple <BigRational, int> Normalize(BigRational r) { if (r.IsNegative) { Tuple <BigRational, int> result = Normalize(-r); return(new Tuple <BigRational, int>(-result.Item1, result.Item2)); } Stack <BigRational> powers = new Stack <BigRational>(); Stack <int> exponents = new Stack <int>(); BigRational currentPower; int currentExponent; int finalExponent = 0; if (r < One) { currentPower = OneHalf; currentExponent = -1; while (r < currentPower) { powers.Push(currentPower); exponents.Push(currentExponent); currentPower *= currentPower; currentExponent *= 2; } while (powers.Count > 0) { currentPower = powers.Pop(); currentExponent = exponents.Pop(); if (r < currentPower) { r /= currentPower; finalExponent += currentExponent; } } } else { currentPower = Two; currentExponent = 1; while (r > currentPower) { powers.Push(currentPower); exponents.Push(currentExponent); currentPower *= currentPower; currentExponent *= 2; } while (powers.Count > 0) { currentPower = powers.Pop(); currentExponent = exponents.Pop(); if (r > currentPower) { r /= currentPower; finalExponent += currentExponent; } } } while (r >= Two) { r /= Two; finalExponent += 1; } while (r < One) { r *= Two; finalExponent -= 1; } return(new Tuple <BigRational, int>(r, finalExponent)); }
public static BigRational Max(BigRational a, BigRational b) { return((a > b) ? a : b); }
public static BigRational Min(BigRational a, BigRational b) { return((a < b) ? a : b); }