// example_float.cpp -- Float API examples (float.html) #include #include #include using namespace calx; // Pi computation void demo_pi() { std::cout << "=== Pi Computation ===\n"; Float::setDefaultPrecision(1000); Float pi = Float::pi(1000); std::cout << pi.toDecimalString(1000) << std::endl; } // Multi-precision exp / log void demo_exp_log() { std::cout << "\n=== Multi-Precision exp / log ===\n"; int prec = 30; Float::setDefaultPrecision(prec); Float x("1.5"); Float ex = exp(x, prec); // e^1.5 Float lx = log(ex, prec); // ln(e^1.5) == 1.5 std::cout << "exp(1.5) = " << ex.toDecimalString(prec) << "\n"; std::cout << "log(exp(1.5)) = " << lx.toDecimalString(prec) << "\n"; } // Safe propagation of NaN / Infinity void demo_nan_infinity() { std::cout << "\n=== Safe Propagation of NaN / Infinity ===\n"; Float inf = Float::positiveInfinity(); Float nan = Float::nan(); Float z = Float::zero(); Float r1 = inf + Float(1); // +Inf Float r2 = inf - inf; // NaN Float r3 = nan + Float(42); // NaN Float r4 = Float(1) / z; // +Inf std::cout << "Inf + 1 = " << r1 << "\n"; std::cout << "Inf - Inf = " << r2 << "\n"; std::cout << "NaN + 42 = " << r3 << "\n"; std::cout << "1 / 0 = " << r4 << "\n"; } // Precision control and constant caching void demo_precision_cache() { std::cout << "\n=== Precision Control & Constant Cache ===\n"; using Clock = std::chrono::high_resolution_clock; auto t0 = Clock::now(); Float pi1 = Float::pi(10000); // first call: computed auto t1 = Clock::now(); Float pi2 = Float::pi(10000); // second call: returned from cache auto t2 = Clock::now(); Float pi3 = Float::pi(50000); // different precision: recomputed auto t3 = Clock::now(); Float pi4 = Float::pi(50000); // returned from cache auto t4 = Clock::now(); auto us = [](auto d) { return std::chrono::duration_cast(d).count(); }; std::cout << "pi(10000) 1st call (computed): " << us(t1-t0) << " us\n"; std::cout << "pi(10000) 2nd call (from cache): " << us(t2-t1) << " us\n"; std::cout << "pi(50000) 1st call (recomputed): " << us(t3-t2) << " us\n"; std::cout << "pi(50000) 2nd call (from cache): " << us(t4-t3) << " us\n"; // Rounding mode: display 1/3 in binary // 1/3 (binary) = 0.01010101... (infinite repeating) // setPrecision(1) -> internal 12-bit precision, difference appears in trailing bits std::cout << "\n--- Rounding Mode (1/3 in binary) ---\n"; std::cout << " 1/3 (binary) = 0.010101... (infinite)\n\n"; auto showRound = [](const char* name, RoundingMode mode) { Float::setRoundingMode(mode); Float pos = Float(1, 30) / Float(3, 30); Float neg = Float(-1, 30) / Float(3, 30); pos.setPrecision(1); neg.setPrecision(1); int bits = static_cast(pos.mantissa().bitLength()) + 1; std::cout << " " << name << ": 1/3 -> " << pos.toString(2, bits) << " -1/3 -> " << neg.toString(2, bits) << "\n"; }; showRound("ToNearest (default)", RoundingMode::ToNearest); showRound("TowardZero ", RoundingMode::TowardZero); showRound("TowardPositive ", RoundingMode::TowardPositive); showRound("TowardNegative ", RoundingMode::TowardNegative); Float::setRoundingMode(RoundingMode::ToNearest); } int main() { demo_pi(); demo_exp_log(); demo_nan_infinity(); demo_precision_cache(); return 0; }