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