#include "maths/format.h" #include #include #include static const double EPSILON = 1e-10; static const double SQRT_2 = 1.4142135623730951; static const double INV_SQRT_2 = 0.7071067811865475; static const double INV_SQRT_8 = 0.3535533905932738; static const double INV_SQRT_32 = 0.1767766952966369; static bool approx_eq(double a, double b) { return fabs(a - b) < EPSILON; } static bool real_symbolic(double v, char *out, size_t cap) { double abs_v = fabs(v); const char *sign = v < 0.0 ? "-" : ""; if (approx_eq(abs_v, 0.0)) { snprintf(out, cap, "%s", "0"); return true; } const char *sym = NULL; if (approx_eq(abs_v, 1.0)) sym = "1"; else if (approx_eq(abs_v, 0.5)) sym = "½"; else if (approx_eq(abs_v, 0.25)) sym = "¼"; else if (approx_eq(abs_v, 0.75)) sym = "¾"; else if (approx_eq(abs_v, 0.125)) sym = "⅛"; else if (approx_eq(abs_v, SQRT_2)) sym = "√2"; else if (approx_eq(abs_v, INV_SQRT_2)) sym = "¹⁄√2"; else if (approx_eq(abs_v, INV_SQRT_8)) sym = "¹⁄√8"; else if (approx_eq(abs_v, INV_SQRT_32)) sym = "¹⁄√32"; else if (approx_eq(abs_v, 2.0)) sym = "2"; else if (approx_eq(abs_v, 1.0 / 3.0)) sym = "⅓"; else if (approx_eq(abs_v, 2.0 / 3.0)) sym = "⅔"; else return false; snprintf(out, cap, "%s%s", sign, sym); return true; } char *psi_format_amplitude(struct PsiComplex c, char *out, size_t cap) { double re = c.real; double im = c.imaginary; bool re_zero = approx_eq(fabs(re), 0.0); bool im_zero = approx_eq(fabs(im), 0.0); if (re_zero && im_zero) { snprintf(out, cap, "%s", "0"); return out; } if (im_zero) { if (!real_symbolic(re, out, cap)) snprintf(out, cap, "%.4f", re); return out; } if (re_zero) { if (approx_eq(fabs(im), 1.0)) { snprintf(out, cap, "%s", im > 0.0 ? "i" : "-i"); return out; } char sym[32]; if (real_symbolic(im, sym, sizeof sym)) snprintf(out, cap, "%si", sym); else snprintf(out, cap, "%.4fi", im); return out; } char re_str[32]; if (!real_symbolic(re, re_str, sizeof re_str)) snprintf(re_str, sizeof re_str, "%.4f", re); char im_str[32]; if (approx_eq(fabs(im), 1.0)) { snprintf(im_str, sizeof im_str, "%s", im > 0.0 ? "+i" : "-i"); } else { const char *sign = im > 0.0 ? "+" : "-"; char sym[32]; if (real_symbolic(fabs(im), sym, sizeof sym)) snprintf(im_str, sizeof im_str, "%s%si", sign, sym); else snprintf(im_str, sizeof im_str, "%s%.4fi", sign, fabs(im)); } snprintf(out, cap, "%s%s", re_str, im_str); return out; } char *psi_format_probability(double p, char *out, size_t cap) { if (approx_eq(p, 0.0)) snprintf(out, cap, "%s", "0"); else if (approx_eq(p, 1.0)) snprintf(out, cap, "%s", "1"); else if (approx_eq(p, 0.5)) snprintf(out, cap, "%s", "½"); else if (approx_eq(p, 0.25)) snprintf(out, cap, "%s", "¼"); else if (approx_eq(p, 0.75)) snprintf(out, cap, "%s", "¾"); else if (approx_eq(p, 0.125)) snprintf(out, cap, "%s", "⅛"); else if (approx_eq(p, 0.0625)) snprintf(out, cap, "%s", "¹⁄₁₆"); else if (approx_eq(p, 1.0 / 3.0)) snprintf(out, cap, "%s", "⅓"); else if (approx_eq(p, 2.0 / 3.0)) snprintf(out, cap, "%s", "⅔"); else snprintf(out, cap, "%.4f", p); return out; }