MCPcopy Create free account
hub / github.com/FastLED/FastLED / ieee754_format_decimal

Function ieee754_format_decimal

src/fl/stl/ieee754_string.cpp.hpp:439–553  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

437}
438
439fl::string ieee754_format_decimal(u32 bits, int precision) FL_NOEXCEPT {
440 if (precision < 0) precision = 0;
441 if (precision > 9) precision = 9;
442
443 const bool neg = (bits >> 31) & 1u;
444 const int biased_exp = static_cast<int>((bits >> 23) & 0xFFu);
445 const u32 mant_bits = bits & 0x7FFFFFu;
446
447 // Inf / NaN.
448 if (biased_exp == 0xFF) {
449 if (mant_bits != 0) return fl::string("nan");
450 return neg ? fl::string("-inf") : fl::string("inf");
451 }
452
453 fl::string s;
454
455 auto append_zero_with_precision = [&]() {
456 s += "0";
457 if (precision > 0) {
458 s += ".";
459 for (int i = 0; i < precision; ++i) s += "0";
460 }
461 };
462
463 // +/- 0 (and any subnormal -- those collapse to zero per the parser's
464 // contract, so the serializer matches).
465 if (biased_exp == 0) {
466 if (neg) s += "-";
467 append_zero_with_precision();
468 return s;
469 }
470
471 // Normal number: value = mantissa_full * 2**bin_exp.
472 // mantissa_full carries the implicit leading 1.
473 const u32 mantissa_full = mant_bits | 0x800000u; // 24 bits
474 const int bin_exp_raw = biased_exp - 127 - 23; // signed
475
476 // Lift to a 64-bit normalized representation so we can multiply against
477 // the shared pow10 table. mantissa_full's bit 23 is set, so shifting left by 40
478 // puts that set bit in position 63.
479 const u64 mant64 = static_cast<u64>(mantissa_full) << 40;
480 const int bin_exp = bin_exp_raw - 40;
481
482 // Look up the normalized representation of 10**precision.
483 const fl::size idx = static_cast<fl::size>(precision - kPow10KMin);
484 const u64 pow_mant = kPow10Mant[idx];
485 const int pow_exp = kPow10BExp[idx];
486
487 // Multiply via the same widening helper the parser uses.
488 u64 scaled_hi = mul_hi_u64(mant64, pow_mant);
489 int scaled_bin_exp = bin_exp + pow_exp + 64;
490 if ((scaled_hi & 0x8000000000000000ull) == 0) {
491 scaled_hi <<= 1;
492 --scaled_bin_exp;
493 }
494
495 // Convert (scaled_hi, scaled_bin_exp) to a u64 integer count of
496 // `precision` decimal places. Overflow on the way up clamps to +/- inf;

Callers 2

acceptMethod · 0.85
FL_TEST_FILEFunction · 0.85

Calls 4

mul_hi_u64Function · 0.85
append_u64_decimalFunction · 0.85
utoa64Function · 0.85
stringClass · 0.70

Tested by

no test coverage detected