00001 #include "multiprec.h"
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <assert.h>
00005
00018 static const int digit_prec = DIGIT_BIT/4 + (DIGIT_BIT%4!=0);
00019
00032 inline static int
00033 do_snprint(char *buf, size_t len, mp_cref_t mz, digit_t radix)
00034 {
00035 int ret = 0;
00036 size_t tmp_used = mz->used;
00037 digit_t *tmp;
00038
00039 if (tmp_used == 0)
00040 {
00041 if (len > 0) buf[len-1] = '0';
00042 return 1;
00043 }
00044
00045 YMP_TEMP_ALLOCATE(tmp, digit_t, tmp_used);
00046 memcpy(tmp, mz->digits, sizeof(digit_t)*tmp_used);
00047
00048 do
00049 {
00050 digit_t d = ymp_divmodabs_digit(tmp, tmp, radix, tmp_used);
00051 if (!tmp[tmp_used-1]) --tmp_used;
00052
00053 if (len-- > 0) buf[len] = "0123456789abcdefghijklmnopqrstuvwxyz"[d];
00054
00055 ++ret;
00056 } while (tmp_used != 0);
00057
00058 if (len-- > 0 && mz->sign) {buf[len] = '-'; ++ret;}
00059 return ret;
00060 }
00061
00070 int
00071 ymp_fprint(FILE *fp, mp_cref_t mz, digit_t radix)
00072 {
00073 int ret;
00074 char *buf;
00075 size_t buf_len = digit_len_to_str_len(mz->used, radix);
00076
00077 YMP_TEMP_ALLOCATE(buf, char, buf_len);
00078 ret = do_snprint(buf, buf_len, mz, radix);
00079 assert(ret <= buf_len);
00080 return fwrite(buf+buf_len-ret, 1, ret, fp);
00081 }
00082
00093 int
00094 ymp_snprint(char *buf, size_t len, mp_cref_t mz, digit_t radix)
00095 {
00096 int ret;
00097 char *new_buf;
00098 size_t new_buf_len = digit_len_to_str_len(mz->used, radix);
00099
00100 YMP_TEMP_ALLOCATE(new_buf, char, new_buf_len);
00101 ret = do_snprint(new_buf, new_buf_len, mz, radix);
00102 assert(ret <= new_buf_len);
00103
00104 if (ret > len) memcpy(buf, new_buf, len);
00105 else memcpy(buf, new_buf+new_buf_len-ret, ret);
00106 return ret;
00107 }
00108
00109
00120 int ymp_print_hex(FILE *fp, mp_cref_t mz)
00121 {
00122 int ret = 0;
00123 size_t i;
00124
00125 if (mz->sign) { putc('-', fp); ++ret; }
00126
00127 fputs("0x", fp); ret += 2;
00128
00129 i = mz->used;
00130 if (i == 0)
00131 {
00132 putc('0', fp); ++ret;
00133 }
00134 else
00135 {
00136 ret += fprintf(fp, "%x", mz->digits[--i]);
00137 while (i-- != 0)
00138 {
00139 ret += fprintf(fp, "%0*x", digit_prec, mz->digits[i]);
00140 }
00141 }
00142 return ret;
00143 }
00144
00145
00152 void ymp_dump(FILE *fp, mp_cref_t mz)
00153 {
00154 size_t i;
00155
00156 fprintf(fp, "{mz used=%zu len=%zu, ", mz->used, mz->len);
00157 putc((mz->sign)?'-':'+', fp);
00158 for (i = 0; i < mz->used; ++i)
00159 fprintf(fp, " %0*x", digit_prec, mz->digits[i]);
00160
00161 if (mz->used < mz->len)
00162 {
00163 fputs(" |", fp);
00164 for ( ; i < mz->len; ++i)
00165 fprintf(fp, " %0*x", digit_prec, mz->digits[i]);
00166 }
00167 putc('}', fp);
00168 }
00169
00170