static int f2s_buffered_n(float f, Span <char> result) { // Step 1: Decode the floating-point number, and unify normalized and subnormal cases. uint bits = float_to_bits(f); // Decode bits into sign, mantissa, and exponent. bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; uint ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1); uint ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1); // Case distinction; exit early for the easy cases. if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) { return(copy_special_str(result, ieeeSign, Convert.ToBoolean(ieeeExponent), Convert.ToBoolean(ieeeMantissa))); } floating_decimal_32 v = f2d(ieeeMantissa, ieeeExponent); return(to_chars(v, ieeeSign, result)); }
static int to_chars(floating_decimal_32 v, bool sign, Span <char> result) { // Step 5: Print the decimal representation. int index = 0; if (sign) { result[index++] = '-'; } uint output = v.mantissa; int olength = decimalLength9(output); // Print the decimal digits. // The following code is equivalent to: // for (uint i = 0; i < olength - 1; ++i) { // uint c = output % 10; output /= 10; // result[index + olength - i] = (char) ('0' + c); // } // result[index] = '0' + output % 10; int i = 0; while (output >= 10000) { uint c = output % 10000; output /= 10000; uint c0 = (c % 100) << 1; uint c1 = (c / 100) << 1; memcpy(result.Slice(index + olength - i - 1), DIGIT_TABLE, c0, 2); memcpy(result.Slice(index + olength - i - 3), DIGIT_TABLE, c1, 2); i += 4; } if (output >= 100) { uint c = (output % 100) << 1; output /= 100; memcpy(result.Slice(index + olength - i - 1), DIGIT_TABLE, c, 2); i += 2; } if (output >= 10) { uint c = output << 1; // We can't use memcpy here: the decimal dot goes between these two digits. result[index + olength - i] = DIGIT_TABLE[c + 1]; result[index] = DIGIT_TABLE[c]; } else { result[index] = (char)('0' + output); } // Print decimal point if needed. if (olength > 1) { result[index + 1] = '.'; index += olength + 1; } else { ++index; } // Print the exponent. result[index++] = 'E'; int exp = v.exponent + (int)olength - 1; if (exp < 0) { result[index++] = '-'; exp = -exp; } if (exp >= 10) { memcpy(result.Slice(index), DIGIT_TABLE, 2 * exp, 2); index += 2; } else { result[index++] = (char)('0' + exp); } return(index); }