154 lines
2.7 KiB
C
154 lines
2.7 KiB
C
|
|
#include <assert.h>
|
|
|
|
#include <debug.h>
|
|
|
|
#include <string/new.h>
|
|
#include <string/free.h>
|
|
|
|
#include <stringtree/new.h>
|
|
#include <stringtree/append.h>
|
|
#include <stringtree/prepend.h>
|
|
#include <stringtree/free.h>
|
|
|
|
#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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|