Merge pull request #177 from wasabiz/number-string

Number string
This commit is contained in:
Yuichi Nishiwaki 2014-07-27 14:49:25 +09:00
commit 6f7543e3a2
1 changed files with 62 additions and 3 deletions

View File

@ -28,6 +28,59 @@ lcm(int a, int b)
return fabs((double)a * b) / gcd(a, b); return fabs((double)a * b) / gcd(a, b);
} }
/**
* Returns the length of string representing val.
* radix is between 2 and 36 (inclusive).
* No error checks are performed in this function.
*/
static int
number_string_length(int val, int radix)
{
long long v = val; /* in case val == INT_MIN */
int count = 0;
if (val == 0) {
return 1;
}
if (val < 0) {
v = - v;
count = 1;
}
while (v > 0) {
++count;
v /= radix;
}
return count;
}
/**
* Returns the string representing val.
* radix is between 2 and 36 (inclusive).
* This function overwrites buffer and stores the result.
* No error checks are performed in this function. It is caller's responsibility to avoid buffer-overrun.
*/
static void
number_string(int val, int radix, int length, char *buffer) {
const char digits[37] = "0123456789abcdefghijklmnopqrstuvwxyz";
long long v = val;
int i;
if (val == 0) {
buffer[0] = '0';
buffer[1] = '\0';
return;
}
if (val < 0) {
buffer[0] = '-';
v = -v;
}
for(i = length - 1; v > 0; --i) {
buffer[i] = digits[v % radix];
v /= radix;
}
buffer[length] = '\0';
return;
}
static pic_value static pic_value
pic_number_real_p(pic_state *pic) pic_number_real_p(pic_state *pic)
{ {
@ -748,10 +801,16 @@ pic_number_number_to_string(pic_state *pic)
pic_get_args(pic, "F|i", &f, &e, &radix); pic_get_args(pic, "F|i", &f, &e, &radix);
if (e) { if (radix < 2 || radix > 36) {
char buf[snprintf(NULL, 0, "%d", (int)f) + 1]; pic_errorf(pic, "number->string: invalid radix %d (between 2 and 36, inclusive)", radix);
}
snprintf(buf, sizeof buf, "%d", (int)f); if (e) {
int ival = (int) f;
int ilen = number_string_length(ival, radix);
char buf[ilen + 1];
number_string(ival, radix, ilen, buf);
return pic_obj_value(pic_str_new(pic, buf, sizeof buf - 1)); return pic_obj_value(pic_str_new(pic, buf, sizeof buf - 1));
} }