/// <summary> /// Convert a 32-bit Ryu floating point number to a roundtrip notation string. /// </summary> public void ToRoundtripString(StringBuilder result, RyuFormatOptions options, NumberFormatInfo info = null) { // Step 5: Print the decimal representation if (info == null) { info = CultureInfo.CurrentCulture.NumberFormat; } if (sign) { result.Append(info.NegativeSign); } #if DEBUG if (info.NumberDecimalSeparator.Length > 1) { throw new ArgumentException("Requires a single character decimal point"); } #endif // Print the decimal digits uint mantissa = this.mantissa; int olength = RyuUtils.DecimalLength9(mantissa), start = result.Length, index = olength + start; result.Length = index + 1; index = RyuUtils.PrintGroups42(result, ref mantissa, index); // Group of 1 if (mantissa >= 10U) { string digits = RyuTables.DIGIT_TABLE[mantissa]; // We can't use memcpy here: the decimal dot goes between these two digits result[index--] = digits[1]; result[start] = digits[0]; } else { result[start] = mantissa.DigitToChar(); } // Print decimal point if needed if (olength > 1) { result[start + 1] = info.NumberDecimalSeparator[0]; index += olength; } result.Length = index; RyuUtils.AppendExponent(result, exponent + olength - 1, options, info); }
/// <summary> /// Convert a 64-bit Ryu floating point number to a roundtrip notation string. /// </summary> public void ToRoundtripString(StringBuilder result, RyuFormatOptions options, NumberFormatInfo info = null) { // Step 5: Print the decimal representation if (info == null) { info = CultureInfo.CurrentCulture.NumberFormat; } if (sign) { result.Append(info.NegativeSign); } #if DEBUG if (info.NumberDecimalSeparator.Length > 1) { throw new ArgumentException("Requires a single character decimal point"); } #endif ulong mantissa = this.mantissa; uint mantissaShort; int olength = RyuUtils.DecimalLength17(mantissa), start = result.Length, index = olength + start; result.Length = index + 1; // Print the decimal digits: group of 8 if ((mantissa >> 32) != 0U) { // We prefer 32-bit operations, even on 64-bit platforms. // We have at most 17 digits, and uint can store 9 digits. // If output doesn't fit into uint, we cut off 8 digits, // so the rest will fit into uint ulong q = mantissa / 100000000UL; mantissaShort = (uint)mantissa - 100000000U * (uint)q; uint o10000 = mantissaShort / 10000U; uint c0 = mantissaShort - 10000U * o10000, d0 = o10000 % 10000U; uint c1 = c0 / 100U, d1 = d0 / 100U; mantissa = q; index = result.WriteDigits(index, c0 - 100U * c1); index = result.WriteDigits(index, c1); index = result.WriteDigits(index, d0 - 100U * d1); index = result.WriteDigits(index, d1); } mantissaShort = (uint)mantissa; index = RyuUtils.PrintGroups42(result, ref mantissaShort, index); // Group of 1 if (mantissaShort >= 10U) { string digits = RyuTables.DIGIT_TABLE[mantissaShort]; // We can't use memcpy here: the decimal dot goes between these two digits result[index--] = digits[1]; result[start] = digits[0]; } else { result[start] = mantissaShort.DigitToChar(); } // Print decimal point if needed if (olength > 1) { result[start + 1] = info.NumberDecimalSeparator[0]; index += olength; } result.Length = index; RyuUtils.AppendExponent(result, exponent + olength - 1, options, info); }