[njs] Number.toString(radix).
Igor Sysoev
igor at sysoev.ru
Wed Jun 1 12:50:23 UTC 2016
details: http://hg.nginx.org/njs/rev/23ff7c369101
branches:
changeset: 102:23ff7c369101
user: Igor Sysoev <igor at sysoev.ru>
date: Tue Apr 19 17:26:25 2016 +0300
description:
Number.toString(radix).
diffstat:
njs/njs_number.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++-
njs/test/njs_unit_test.c | 29 ++++++++++++++
2 files changed, 121 insertions(+), 2 deletions(-)
diffs (164 lines):
diff -r e411e0cbd20d -r 23ff7c369101 njs/njs_number.c
--- a/njs/njs_number.c Fri Apr 15 18:01:40 2016 +0300
+++ b/njs/njs_number.c Tue Apr 19 17:26:25 2016 +0300
@@ -22,6 +22,10 @@
#include <stdio.h>
+static njs_ret_t njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string,
+ const njs_value_t *number, uint32_t radix);
+
+
double
njs_value_to_number(njs_value_t *value)
{
@@ -313,6 +317,7 @@ static njs_ret_t
njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t unused)
{
+ double radix;
njs_value_t *value;
value = &args[0];
@@ -328,7 +333,91 @@ njs_number_prototype_to_string(njs_vm_t
}
}
- return njs_number_to_string(vm, &vm->retval, value);
+ if (nargs == 1 || args[1].data.u.number == 10) {
+ return njs_number_to_string(vm, &vm->retval, value);
+ }
+
+ radix = args[1].data.u.number;
+
+ if (radix < 2 || radix > 36 || radix != (int) radix) {
+ vm->exception = &njs_exception_range_error;
+ return NXT_ERROR;
+ }
+
+ return njs_number_to_string_radix(vm, &vm->retval, value, radix);
+}
+
+
+/*
+ * The radix equal to 2 produces the longest intergral value of a number
+ * and the maximum value consists of 1024 digits and minus sign.
+ */
+
+#define NJS_STRING_RADIX_INTERGRAL_LEN (1 + 1024)
+#define NJS_STRING_RADIX_FRACTION_LEN (1 + 54)
+#define NJS_STRING_RADIX_LEN \
+ (NJS_STRING_RADIX_INTERGRAL_LEN + NJS_STRING_RADIX_FRACTION_LEN)
+
+
+static njs_ret_t
+njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string,
+ const njs_value_t *number, uint32_t radix)
+{
+ u_char *p, *f, *start, *end;
+ double n, next;
+ size_t size;
+ uint8_t reminder;
+ u_char buf[NJS_STRING_RADIX_LEN];
+
+ static const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+ end = buf + NJS_STRING_RADIX_LEN;
+ p = buf + NJS_STRING_RADIX_INTERGRAL_LEN;
+
+ n = number->data.u.number;
+
+ if (n < 0) {
+ n = -n;
+ }
+
+ do {
+ next = trunc(n / radix);
+ reminder = n - next * radix;
+ *(--p) = digits[reminder];
+ n = next;
+ } while (n != 0);
+
+ n = number->data.u.number;
+
+ if (n < 0) {
+ *(--p) = '-';
+ }
+
+ f = buf + NJS_STRING_RADIX_INTERGRAL_LEN;
+
+ n = n - trunc(n);
+
+ if (n != 0) {
+ *f++ = '.';
+
+ do {
+ n = n * radix;
+ reminder = trunc(n);
+ *f++ = digits[reminder];
+ n = n - reminder;
+ } while (n != 0 && f < end);
+ }
+
+ size = f - p;
+
+ start = njs_string_alloc(vm, string, size, size);
+
+ if (nxt_fast_path(start != NULL)) {
+ memcpy(start, p, size);
+ return NXT_OK;
+ }
+
+ return NXT_ERROR;
}
@@ -349,7 +438,8 @@ static const njs_object_prop_t njs_numb
{
.type = NJS_METHOD,
.name = njs_string("toString"),
- .value = njs_native_function(njs_number_prototype_to_string, 0, 0),
+ .value = njs_native_function(njs_number_prototype_to_string, 0,
+ NJS_SKIP_ARG, NJS_NUMBER_ARG),
},
};
diff -r e411e0cbd20d -r 23ff7c369101 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Fri Apr 15 18:01:40 2016 +0300
+++ b/njs/test/njs_unit_test.c Tue Apr 19 17:26:25 2016 +0300
@@ -92,6 +92,35 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("\n +1"),
nxt_string("1") },
+ /* Number.toString(radix) method. */
+
+ { nxt_string("0..toString(2)"),
+ nxt_string("0") },
+
+ { nxt_string("240..toString(2)"),
+ nxt_string("11110000") },
+
+ { nxt_string("Math.pow(-2, 1023).toString(2).length"),
+ nxt_string("1025") },
+
+ { nxt_string("8.0625.toString(2)"),
+ nxt_string("1000.0001") },
+
+ { nxt_string("(1/3).toString(2)"),
+ nxt_string("0.010101010101010101010101010101010101010101010101010101") },
+
+ { nxt_string("9999..toString(3)"),
+ nxt_string("111201100") },
+
+ { nxt_string("-9999..toString(3)"),
+ nxt_string("-111201100") },
+
+ { nxt_string("81985529216486895..toString(16)"),
+ nxt_string("123456789abcdf0") },
+
+ { nxt_string("1845449130881..toString(36)"),
+ nxt_string("njscript") },
+
/* An object "valueOf/toString" methods. */
{ nxt_string("var a = { valueOf: function() { return 1 } }; +a"),
More information about the nginx-devel
mailing list