forked from ibphoenix/tomsfastmath
implement fp_toradix_n()
It is not implemened yet, just added to the headerfile. Therefore I don't think it is a ABI breakage if I change maxlen from int to unsigned int. The function releases fp_toradix() for the work which in turn now calls fp_toradix_n() with a largest possible maxlen parameter. Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
This commit is contained in:
parent
8aba8446f2
commit
f734a43b05
@ -9,51 +9,95 @@
|
|||||||
*/
|
*/
|
||||||
#include <tfm.h>
|
#include <tfm.h>
|
||||||
|
|
||||||
int fp_toradix(fp_int *a, char *str, int radix)
|
/**
|
||||||
|
* a: pointer to fp_int representing the input number
|
||||||
|
* str: output buffer
|
||||||
|
* radix: number of character to use for encoding of the number
|
||||||
|
* maxlen: maximum number of the buffer that can be used
|
||||||
|
*
|
||||||
|
* The radix value can be in the range 2 to 64. This function converts number
|
||||||
|
* a into a string str. This function writes at most size bytes (including the
|
||||||
|
* terminating null byte to str. It behaves like snprintf(3) in regard to this.
|
||||||
|
*
|
||||||
|
* Return: If invalid parameter are detected a negative value is returned. On
|
||||||
|
* success the function returns the number of bytes that would be written if
|
||||||
|
* the function had enough space. Thus a return value of maxlen or more means
|
||||||
|
* that the function was not able store all characters and the output is
|
||||||
|
* incomplete.
|
||||||
|
*/
|
||||||
|
int fp_toradix_n(fp_int *a, char *str, int radix, unsigned int maxlen)
|
||||||
{
|
{
|
||||||
int digs;
|
int digs;
|
||||||
fp_int t;
|
fp_int t;
|
||||||
fp_digit d;
|
fp_digit d;
|
||||||
char *_s = str;
|
char *_s = str;
|
||||||
|
unsigned int wrote;
|
||||||
|
|
||||||
/* check range of the radix */
|
/* check range of the radix */
|
||||||
if (radix < 2 || radix > 64) {
|
if (radix < 2 || radix > 64)
|
||||||
return FP_VAL;
|
return -1;
|
||||||
|
|
||||||
|
/* quick check for zero */
|
||||||
|
if (fp_iszero(a) == 1) {
|
||||||
|
if (maxlen >= 2)
|
||||||
|
*str++ = '0';
|
||||||
|
if (maxlen >= 1)
|
||||||
|
*str = '\0';
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* quick out if its zero */
|
wrote = 0;
|
||||||
if (fp_iszero(a) == 1) {
|
|
||||||
*str++ = '0';
|
|
||||||
*str = '\0';
|
|
||||||
return FP_OKAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
fp_init_copy(&t, a);
|
fp_init_copy(&t, a);
|
||||||
|
|
||||||
/* if it is negative output a - */
|
/* if it is negative output a - */
|
||||||
if (t.sign == FP_NEG) {
|
if (t.sign == FP_NEG) {
|
||||||
++_s;
|
++_s;
|
||||||
*str++ = '-';
|
wrote++;
|
||||||
|
if (wrote < maxlen)
|
||||||
|
*str++ = '-';
|
||||||
t.sign = FP_ZPOS;
|
t.sign = FP_ZPOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
digs = 0;
|
digs = 0;
|
||||||
while (fp_iszero (&t) == FP_NO) {
|
while (fp_iszero (&t) == FP_NO) {
|
||||||
fp_div_d (&t, (fp_digit) radix, &t, &d);
|
fp_div_d (&t, (fp_digit) radix, &t, &d);
|
||||||
*str++ = fp_s_rmap[d];
|
wrote++;
|
||||||
|
if (wrote < maxlen)
|
||||||
|
*str++ = fp_s_rmap[d];
|
||||||
++digs;
|
++digs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reverse the digits of the string. In this case _s points
|
/* reverse the digits of the string. In this case _s points
|
||||||
* to the first digit [exluding the sign] of the number]
|
* to the first digit [exluding the sign] of the number]
|
||||||
*/
|
*/
|
||||||
fp_reverse ((unsigned char *)_s, digs);
|
if (wrote < maxlen)
|
||||||
|
fp_reverse ((unsigned char *)_s, digs);
|
||||||
|
|
||||||
/* append a NULL so the string is properly terminated */
|
/* append a NULL so the string is properly terminated */
|
||||||
*str = '\0';
|
if (maxlen >= 1)
|
||||||
return FP_OKAY;
|
*str = '\0';
|
||||||
|
return wrote;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* $Source$ */
|
/**
|
||||||
/* $Revision$ */
|
* a: pointer to fp_int representing the input number
|
||||||
/* $Date$ */
|
* str: output buffer
|
||||||
|
* radix: number of character to use for encoding of the number
|
||||||
|
*
|
||||||
|
* The radix value can be in the range 2 to 64. This function converts number
|
||||||
|
* a into a string str. Please don't use this function because a too small
|
||||||
|
* chosen str buffer would lead to an overflow which can not be detected.
|
||||||
|
* Please use fp_toradix_n() instead.
|
||||||
|
*
|
||||||
|
* Return: FP_VAL on error, FP_OKAY on success.
|
||||||
|
*/
|
||||||
|
int fp_toradix(fp_int *a, char *str, int radix)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = fp_toradix_n(a, str, radix, UINT_MAX);
|
||||||
|
if (ret < 0)
|
||||||
|
return FP_VAL;
|
||||||
|
return FP_OKAY;
|
||||||
|
}
|
||||||
|
@ -465,7 +465,7 @@ int fp_read_radix(fp_int *a, char *str, int radix);
|
|||||||
|
|
||||||
int fp_radix_size(fp_int *a, int radix, int *size);
|
int fp_radix_size(fp_int *a, int radix, int *size);
|
||||||
int fp_toradix(fp_int *a, char *str, int radix);
|
int fp_toradix(fp_int *a, char *str, int radix);
|
||||||
int fp_toradix_n(fp_int * a, char *str, int radix, int maxlen);
|
int fp_toradix_n(fp_int * a, char *str, int radix, unsigned int maxlen);
|
||||||
|
|
||||||
|
|
||||||
/* VARIOUS LOW LEVEL STUFFS */
|
/* VARIOUS LOW LEVEL STUFFS */
|
||||||
|
Loading…
Reference in New Issue
Block a user