public static DiyFp Normalize(ref DiyFp a) { DiyFp result = a; result.Normalize(); return(result); }
// Returns the two boundaries of first argument. // The bigger boundary (m_plus) is normalized. The lower boundary has the same // exponent as m_plus. internal static void NormalizedBoundaries(long d64, DiyFp mMinus, DiyFp mPlus) { DiyFp v = AsDiyFp(d64); bool significandIsZero = (v.F == KHiddenBit); mPlus.F = (v.F << 1) + 1; mPlus.E = v.E - 1; mPlus.Normalize(); if (significandIsZero && v.E != KDenormalExponent) { // The boundary is closer. Think of v = 1000e10 and v- = 9999e9. // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but // at a distance of 1e8. // The only exception is for the smallest normal: the largest denormal is // at the same distance as its successor. // Note: denormals have the same exponent as the smallest normals. mMinus.F = (v.F << 2) - 1; mMinus.E = v.E - 2; } else { mMinus.F = (v.F << 1) - 1; mMinus.E = v.E - 1; } mMinus.F = mMinus.F << (mMinus.E - mPlus.E); mMinus.E = mPlus.E; }
// Computes the two boundaries of this. // The bigger boundary (m_plus) is normalized. The lower boundary has the same // exponent as m_plus. // Precondition: the value encoded by this Single must be greater than 0. public void NormalizedBoundaries(out DiyFp outMMinus, out DiyFp outMPlus) { var v = this.AsDiyFp(); var __ = new DiyFp((v.f << 1) + 1, v.e - 1); var mPlus = DiyFp.Normalize(ref __); var mMinus = LowerBoundaryIsCloser() ? new DiyFp((v.f << 2) - 1, v.e - 2) : new DiyFp((v.f << 1) - 1, v.e - 1); mMinus.f <<= mMinus.e - mPlus.e; mMinus.e = mPlus.e; outMPlus = mPlus; outMMinus = mMinus; }
private static unsafe int Grisu2(double value, char *buffer, out int K) { var v = new DiyFp(value); v.NormalizedBoundaries(out var w_m, out var w_p); var c_mk = GetCachedPower(w_p.e, out K); var W = v.Normalize() * c_mk; var Wp = w_p * c_mk; var Wm = w_m * c_mk; Wm.f++; Wp.f--; return(DigitGen(W, Wp, Wp.f - Wm.f, buffer, ref K)); }
private static unsafe int Grisu2(double value, char *buffer, out int K) { DiyFp diyFp = new DiyFp(value); DiyFp minus; DiyFp plus; diyFp.NormalizedBoundaries(out minus, out plus); DiyFp cachedPower = GetCachedPower(plus.e, out K); DiyFp w = diyFp.Normalize() * cachedPower; DiyFp mp = plus * cachedPower; DiyFp diyFp2 = minus * cachedPower; diyFp2.f++; mp.f--; return(DigitGen(w, mp, mp.f - diyFp2.f, buffer, ref K)); }