#include #include #include #include #include #include #include #include #include "struct.h" #include "prettyprint.h" static struct stringtree* prettyprint_mpn( mpz_srcptr printme, const wchar_t* digits) { ENTER; struct stringtree* tree = new_stringtree(); mpz_t countdown, digit, ten; mpz_init(digit); mpz_init_set_ui(ten, 10); mpz_init_set(countdown, printme); assert(mpz_sgn(countdown) >= 0); if (mpz_sgn(countdown) == 0) { stringtree_append_cstr(tree, L"0"); } else while (mpz_sgn(countdown)) { mpz_fdiv_qr(countdown, digit, countdown, ten); wchar_t wc = digits[mpz_get_ui(digit)]; dpvwc(wc); struct string* d = new_string(&wc, 1); stringtree_prepend_string(tree, d); free_string(d); } mpz_clear(countdown); mpz_clear(digit); mpz_clear(ten); EXIT; return tree; } struct stringtree* number_prettyprint( struct number* this) { ENTER; struct stringtree* tree = new_stringtree(); mpq_t clone; mpq_init(clone); mpq_set(clone, this->number); if (mpq_sgn(clone) < 0) { stringtree_append_cstr(tree, L"-"); mpq_abs(clone, clone); } mpz_t whole; mpz_init(whole); mpz_fdiv_q(whole, mpq_numref(clone), mpq_denref(clone)); struct stringtree* whole_tree = prettyprint_mpn(whole, L"0123456789"); stringtree_append_stringtree(tree, whole_tree); // subtract whole out of clone: { mpq_t tmp; mpq_init(tmp); mpq_set_z(tmp, whole); mpq_sub(clone, clone, tmp); mpq_clear(tmp); } // print decimal: if (mpq_sgn(clone)) { struct stringtree* num_tree = prettyprint_mpn( mpq_numref(clone), L"⁰¹²³⁴⁵⁶⁷⁸⁹"); struct stringtree* den_tree = prettyprint_mpn( mpq_denref(clone), L"₀₁₂₃₄₅₆₇₈₉"); // stringtree_append_cstr(tree, L" "); stringtree_append_stringtree(tree, num_tree); stringtree_append_cstr(tree, L"/"); stringtree_append_stringtree(tree, den_tree); free_stringtree(num_tree); free_stringtree(den_tree); } free_stringtree(whole_tree); mpz_clear(whole); mpq_clear(clone); EXIT; return tree; }