File Coverage

n128.c
Criterion Covered Total %
statement 243 244 99.5
branch 145 146 99.3
condition n/a
subroutine n/a
pod n/a
total 388 390 99.4


line stmt bran cond sub pod time code
1             /*
2             n128.c - 128-bit integer.
3              
4             Copyright (C) 2012-2014 Tom Harrison
5             Original inet_pton4, inet_pton6 are Copyright (C) 2006 Free Software
6             Foundation.
7             Original interface, and the auth and ip_auth functions, are Copyright
8             (C) 1999-2002 RIPE NCC.
9              
10             This program is free software; you can redistribute it and/or modify
11             it under the terms of the GNU General Public License as published by
12             the Free Software Foundation; either version 2 of the License, or
13             (at your option) any later version.
14              
15             This program is distributed in the hope that it will be useful,
16             but WITHOUT ANY WARRANTY; without even the implied warranty of
17             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18             GNU General Public License for more details.
19              
20             You should have received a copy of the GNU General Public License along
21             with this program; if not, write to the Free Software Foundation, Inc.,
22             51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23             */
24              
25             #include
26             #include
27             #include
28             #include
29             #include
30              
31             #include "n128.h"
32              
33             #ifdef __cplusplus
34             extern "C" {
35             #endif
36              
37             static char *power_strings[] = {
38             "1",
39             "2",
40             "4",
41             "8",
42             "16",
43             "32",
44             "64",
45             "128",
46             "256",
47             "512",
48             "1024",
49             "2048",
50             "4096",
51             "8192",
52             "16384",
53             "32768",
54             "65536",
55             "131072",
56             "262144",
57             "524288",
58             "1048576",
59             "2097152",
60             "4194304",
61             "8388608",
62             "16777216",
63             "33554432",
64             "67108864",
65             "134217728",
66             "268435456",
67             "536870912",
68             "1073741824",
69             "2147483648",
70             "4294967296",
71             "8589934592",
72             "17179869184",
73             "34359738368",
74             "68719476736",
75             "137438953472",
76             "274877906944",
77             "549755813888",
78             "1099511627776",
79             "2199023255552",
80             "4398046511104",
81             "8796093022208",
82             "17592186044416",
83             "35184372088832",
84             "70368744177664",
85             "140737488355328",
86             "281474976710656",
87             "562949953421312",
88             "1125899906842624",
89             "2251799813685248",
90             "4503599627370496",
91             "9007199254740992",
92             "18014398509481984",
93             "36028797018963968",
94             "72057594037927936",
95             "144115188075855872",
96             "288230376151711744",
97             "576460752303423488",
98             "1152921504606846976",
99             "2305843009213693952",
100             "4611686018427387904",
101             "9223372036854775808",
102             "18446744073709551616",
103             "36893488147419103232",
104             "73786976294838206464",
105             "147573952589676412928",
106             "295147905179352825856",
107             "590295810358705651712",
108             "1180591620717411303424",
109             "2361183241434822606848",
110             "4722366482869645213696",
111             "9444732965739290427392",
112             "18889465931478580854784",
113             "37778931862957161709568",
114             "75557863725914323419136",
115             "151115727451828646838272",
116             "302231454903657293676544",
117             "604462909807314587353088",
118             "1208925819614629174706176",
119             "2417851639229258349412352",
120             "4835703278458516698824704",
121             "9671406556917033397649408",
122             "19342813113834066795298816",
123             "38685626227668133590597632",
124             "77371252455336267181195264",
125             "154742504910672534362390528",
126             "309485009821345068724781056",
127             "618970019642690137449562112",
128             "1237940039285380274899124224",
129             "2475880078570760549798248448",
130             "4951760157141521099596496896",
131             "9903520314283042199192993792",
132             "19807040628566084398385987584",
133             "39614081257132168796771975168",
134             "79228162514264337593543950336",
135             "158456325028528675187087900672",
136             "316912650057057350374175801344",
137             "633825300114114700748351602688",
138             "1267650600228229401496703205376",
139             "2535301200456458802993406410752",
140             "5070602400912917605986812821504",
141             "10141204801825835211973625643008",
142             "20282409603651670423947251286016",
143             "40564819207303340847894502572032",
144             "81129638414606681695789005144064",
145             "162259276829213363391578010288128",
146             "324518553658426726783156020576256",
147             "649037107316853453566312041152512",
148             "1298074214633706907132624082305024",
149             "2596148429267413814265248164610048",
150             "5192296858534827628530496329220096",
151             "10384593717069655257060992658440192",
152             "20769187434139310514121985316880384",
153             "41538374868278621028243970633760768",
154             "83076749736557242056487941267521536",
155             "166153499473114484112975882535043072",
156             "332306998946228968225951765070086144",
157             "664613997892457936451903530140172288",
158             "1329227995784915872903807060280344576",
159             "2658455991569831745807614120560689152",
160             "5316911983139663491615228241121378304",
161             "10633823966279326983230456482242756608",
162             "21267647932558653966460912964485513216",
163             "42535295865117307932921825928971026432",
164             "85070591730234615865843651857942052864",
165             "170141183460469231731687303715884105728",
166             "340282366920938463463374607431768211456",
167             };
168              
169             /*
170             * n128_set(): copy N128 value from other N128 value.
171             * @dst: destination N128 object.
172             * @src: source N128 object.
173             */
174             void
175 81781           n128_set(n128_t *dst, n128_t *src)
176             {
177 81781           memcpy(dst, src, sizeof(*dst));
178              
179 81781           return;
180             }
181              
182             /**
183             * n128_set_ui(): set N128 value based on unsigned integer.
184             * @n: the N128 object to be set.
185             * @ui: the value to set.
186             */
187             void
188 44831           n128_set_ui(n128_t *n, unsigned int ui)
189             {
190 44831           n->nums[0] = 0;
191 44831           n->nums[1] = 0;
192 44831           n->nums[2] = 0;
193 44831           n->nums[3] = ui;
194              
195 44831           return;
196             }
197              
198             /**
199             * n128_cmp_ui(): compare N128 value against unsigned integer.
200             * @n: the N128 object.
201             * @ui: unsigned integer.
202             *
203             * Returns 1 if @n is more than @ui, 0 if @n is equal to @ui and -1 if
204             * @n is less than @ui.
205             */
206             int
207 23239           n128_cmp_ui(n128_t *n, unsigned int ui)
208             {
209             return
210 44793 100         (n->nums[0] || n->nums[1] || n->nums[2] || (n->nums[3] > ui))
    100          
    100          
211             ? 1
212 44793 100         : (n->nums[3] == ui)
213             ? 0
214 503 100         : -1;
215             }
216              
217             /**
218             * n128_blsft(): left-shift (circular) N128 value.
219             * @n: the N128 object to shift.
220             * @sft: the number of places by which the object should be shifted.
221             */
222             void
223 23254           n128_blsft(n128_t *n, int sft)
224             {
225             n128_t copy;
226             int i;
227             uint32_t mask;
228             int diff;
229            
230 23254           diff = sft - 31;
231 23254 100         if (diff >= 0) {
232 556           sft = 31;
233             }
234              
235 116270 100         for (i = 0; i < 4; ++i) {
236 93016           copy.nums[i] = n->nums[i];
237             }
238 116270 100         for (i = 0; i < 4; ++i) {
239 93016           n->nums[i] <<= sft;
240             }
241 116270 100         for (i = 0; i < 4; ++i) {
242 93016           mask = ((1 << sft) - 1) << (32 - sft);
243 93016           mask &= copy.nums[(i + 1) % 4];
244 93016           mask >>= (32 - sft);
245 93016           n->nums[i] |= mask;
246             }
247              
248 23254 100         if (diff >= 0) {
249 556           n128_blsft(n, diff);
250             }
251              
252 23254           return;
253             }
254              
255             /**
256             * n128_brsft(): right-shift (circular) N128 value.
257             * @n: the N128 object to shift.
258             * @sft: the number of places by which the object should be shifted.
259             */
260             void
261 22316           n128_brsft(n128_t *n, int sft)
262             {
263             n128_t copy;
264             int i;
265             uint32_t mask;
266             int diff;
267            
268 22316           diff = sft - 31;
269 22316 100         if (diff >= 0) {
270 9           sft = 31;
271             }
272              
273 111580 100         for (i = 0; i < 4; ++i) {
274 89264           copy.nums[i] = n->nums[i];
275             }
276 111580 100         for (i = 0; i < 4; ++i) {
277 89264           n->nums[i] >>= sft;
278             }
279 111580 100         for (i = 0; i < 4; ++i) {
280 89264           mask = ((1 << sft) - 1);
281 89264           mask &= copy.nums[(i + 3) % 4];
282 89264           mask <<= (32 - sft);
283 89264           n->nums[i] |= mask;
284             }
285              
286 22316 100         if (diff >= 0) {
287 9           n128_brsft(n, diff);
288             }
289              
290 22316           return;
291             }
292              
293             /**
294             * n128_and(): bitwise AND two N128 values.
295             * @n1: first N128 object.
296             * @n2: second N128 object.
297             *
298             * The result is stored in the first argument.
299             */
300             void
301 50           n128_and(n128_t *n1, n128_t *n2)
302             {
303             int i;
304              
305 250 100         for (i = 0; i < 4; i++) {
306 200           n1->nums[i] &= n2->nums[i];
307             }
308              
309 50           return;
310             }
311              
312             /**
313             * n128_ior(): bitwise OR two N128 values.
314             * @n1: first N128 object.
315             * @n2: second N128 object.
316             *
317             * The result is stored in the first argument.
318             */
319             void
320 19033           n128_ior(n128_t *n1, n128_t *n2)
321             {
322             int i;
323              
324 95165 100         for (i = 0; i < 4; i++) {
325 76132           n1->nums[i] |= n2->nums[i];
326             }
327              
328 19033           return;
329             }
330              
331             /**
332             * n128_xor(): bitwise XOR two N128 values.
333             * @n1: first N128 object.
334             * @n2: second N128 object.
335             *
336             * The result is stored in the first argument.
337             */
338             void
339 3           n128_xor(n128_t *n1, n128_t *n2)
340             {
341             int i;
342              
343 15 100         for (i = 0; i < 4; i++) {
344 12           n1->nums[i] ^= n2->nums[i];
345             }
346              
347 3           return;
348             }
349              
350             /**
351             * n128_add(): add two N128 values.
352             * @n1: first N128 object.
353             * @n2: second N128 object.
354             *
355             * The result is stored in the first argument. Overflow is as per
356             * an unsigned integer.
357             */
358             int
359 39107           n128_add(n128_t *n1, n128_t *n2)
360             {
361             int i;
362             int j;
363              
364 195535 100         for (i = 0; i < 4; i++) {
365 156428           n1->nums[i] += n2->nums[i];
366             }
367 156428 100         for (i = 1; i < 4; i++) {
368 117321           j = i - 1;
369 117321 100         if (n1->nums[i] < n2->nums[i]) {
370 33678           n1->nums[j]++;
371 67532 100         while (n1->nums[j] == 0 && j--) {
    100          
372 33854           n1->nums[j]++;
373             }
374             }
375             }
376              
377 39107           return 1;
378             }
379              
380             /**
381             * n128_com(): take the complement of an N128 value.
382             * @n: N128 object.
383             *
384             * The result is stored in the argument.
385             */
386             void
387 11364           n128_com(n128_t *n)
388             {
389             int i;
390              
391 56820 100         for (i = 0; i < 4; i++) {
392 45456           n->nums[i] = ~(n->nums[i]);
393             }
394              
395 11364           return;
396             }
397              
398             /**
399             * n128_add_ui(): add an unsigned integer value to an N128 value.
400             * @n: N128 object.
401             *
402             * The result is stored in the first argument. Overflow is as per an
403             * unsigned integer.
404             */
405             int
406 27374           n128_add_ui(n128_t *n, unsigned int ui)
407             {
408             n128_t n2;
409 27374           n128_set_ui(&n2, ui);
410 27374           n128_add(n, &n2);
411              
412 27374           return 1;
413             }
414              
415             /**
416             * n128_sub(): subtract an N128 value from another.
417             * @n1: N128 object (minuend).
418             * @n2: N128 object (subtrahend).
419             *
420             * The result is stored in the first argument. Overflow is not
421             * handled: if @n2 is greater than @n1, the result will be zero.
422             */
423             int
424 11396           n128_sub(n128_t *n1, n128_t *n2)
425             {
426             int res;
427             n128_t n2c;
428 11396           n128_t *n2cp = &n2c;
429            
430 11396           res = n128_cmp(n1, n2);
431 11396 100         if (res < 0) {
432 1           return 0;
433             }
434 11395 100         if (res == 0) {
435 35           n128_set_ui(n1, 0);
436 35           return 1;
437             }
438 11360           n128_set(n2cp, n2);
439 11360           n128_com(n2cp);
440 11360           n128_add_ui(n2cp, 1);
441 11360           n128_add(n1, n2cp);
442              
443 11396           return 1;
444             }
445              
446             /**
447             * n128_tstbit(): test whether a bit is set in an N128 value.
448             * @n: N128 object.
449             * @bit: the bit to test.
450             *
451             * Returns 1 if the bit is set, and zero if it is not. Bits begin at
452             * zero and are ordered from least to most significant.
453             */
454             int
455 7444357           n128_tstbit(n128_t *n, int bit)
456             {
457 7444357           return (n->nums[3 - (bit / 32)] >> (bit % 32)) & 1;
458             }
459              
460             /**
461             * n128_setbit(): set a particular bit in an N128 value.
462             * @n: N128 object.
463             * @bit: the bit to set.
464             *
465             * See n128_tstbit().
466             */
467             void
468 1473833           n128_setbit(n128_t *n, int bit)
469             {
470 1473833           n->nums[3 - (bit / 32)] |= (1 << (bit % 32));
471 1473833           }
472              
473             /**
474             * n128_clrbit(): clear a particular bit in an N128 value.
475             * @n: N128 object.
476             * @bit: the bit to clear.
477             *
478             * See n128_tstbit().
479             */
480             void
481 21999           n128_clrbit(n128_t *n, int bit)
482             {
483 21999           n->nums[3 - (bit / 32)] &= ~(1 << (bit % 32));
484 21999           }
485              
486             /**
487             * n128_cmp(): compare N128 value against another.
488             * @n1: first N128 object.
489             * @n2: second N128 object.
490             *
491             * Returns 1 if @n1 is more than @n2, 0 if @n1 is equal to @n2 and -1 if
492             * @n1 is less than @n2.
493             */
494             int
495 69920           n128_cmp(n128_t *n1, n128_t *n2)
496             {
497 69920           return (n1->nums[0] > n2->nums[0]) ? 1
498 137213 100         : (n1->nums[0] < n2->nums[0]) ? -1
499 102101 100         : (n1->nums[1] > n2->nums[1]) ? 1
500 64379 100         : (n1->nums[1] < n2->nums[1]) ? -1
501 57052 100         : (n1->nums[2] > n2->nums[2]) ? 1
502 46825 100         : (n1->nums[2] < n2->nums[2]) ? -1
503 35126 100         : (n1->nums[3] > n2->nums[3]) ? 1
504 21411 100         : (n1->nums[3] < n2->nums[3]) ? -1
505 5629 100         : 0;
506             }
507              
508             /**
509             * n128_set_str_binary(): set N128 value based on bitstring.
510             * @n: destination N128 object.
511             * @bitstr: the bitstring.
512             * @len: the length of the bitstring.
513             *
514             * The bitstring's bits must be ordered from most to
515             * least significant. Any character in the bitstring that is not the
516             * character '0' will be treated as the character '1'.
517             */
518             void
519 1711           n128_set_str_binary(n128_t *n, const char *bitstr, int len)
520             {
521             int i;
522             int j;
523             int mylen;
524              
525 1711           memset(n, 0, 4 * sizeof(uint32_t));
526 1711           mylen = (len > 128) ? 128 : len;
527              
528 1711 100         if (mylen < 128) {
529 2864 100         for (i = 0; i < (128 - mylen); i++) {
530 2840           n128_clrbit(n, (127 - i));
531             }
532             } else {
533 1687           i = 0;
534             }
535 217879 100         for (j = 0; i < 128; i++, j++) {
536 216168 100         if (bitstr[j] != '0') {
537 131837           n128_setbit(n, (127 - i));
538             }
539             }
540              
541 1711           return;
542             }
543              
544             static void
545 17524           str_subtract(char *buf, int buflen, char *operand, int oplen)
546             {
547             int i;
548             int j;
549 17524           int carry = 0;
550             int diff;
551              
552 415039 100         for (i = buflen - 1, j = oplen - 1; i >= 0 && j >= 0; --i, --j) {
    100          
553 397515           diff = (buf[i] - (operand[j] + carry));
554 397515 100         if (diff >= 0) {
555 201345           buf[i] = diff + '0';
556 201345           carry = 0;
557             } else {
558 196170           buf[i] = diff + '0' + 10;
559 196170           carry = 1;
560             }
561             }
562 17524 100         if (carry == 1) {
563 4480           buf[i]--;
564             }
565              
566 17524           return;
567             }
568              
569             /**
570             * n128_set_str_decimal(): set N128 value based on decimal string.
571             * @n: destination N128 object.
572             * @bitstr: the decimal string.
573             * @len: the length of the decimal string.
574             */
575             int
576 402           n128_set_str_decimal(n128_t *n, const char *str, int len)
577             {
578             int i;
579             char *ps;
580             int ps_len;
581             char buf[40];
582             char *bufp;
583              
584 402 100         if (len > 39) {
585 2           return 0;
586             }
587            
588 400           bufp = buf;
589 400           strncpy(bufp, str, len);
590 400           buf[len] = '\0';
591 400           n128_set_ui(n, 0);
592              
593 13921 100         for (i = 0; i < len; i++) {
594 13522 100         if (!isdigit(str[i])) {
595 1           return 0;
596             }
597             }
598            
599 399 100         if (power_strings[127][0] > str[0]) {
600 3           return 0;
601             }
602              
603 38599 100         for (i = 127; i >= 0; i--) {
604 38563 100         if (!len) {
605 360           break;
606             }
607 38203           ps = power_strings[i];
608 38203           ps_len = strlen(ps);
609 38203 100         if (ps_len > len) {
610 10663           continue;
611             } else {
612 27540 100         if (ps_len == len) {
613 23060 100         if (strcmp(bufp, ps) < 0) {
614 10016           continue;
615             }
616             }
617 17524           str_subtract(bufp, len, ps, ps_len);
618 31038 100         while (*bufp == '0') {
619 13514           ++bufp;
620 13514           --len;
621             }
622 17524           n128_setbit(n, i);
623             }
624             }
625 396 100         if (len) {
626 4           return 0;
627             }
628            
629 402           return 1;
630             }
631              
632             /**
633             * n128_scan0(): return the index of the least significant cleared bit.
634             * @n: N128 object.
635             */
636             int
637 16003           n128_scan0(n128_t *n)
638             {
639             int i;
640              
641 1349151 100         for (i = 0; i < 128; i++) {
642 1348768 100         if (!n128_tstbit(n, i)) {
643 15620           return i;
644             }
645             }
646              
647 383           return INT_MAX;
648             }
649              
650             /**
651             * n128_scan1(): return the index of the least significant set bit.
652             * @n: N128 object.
653             */
654             int
655 16349           n128_scan1(n128_t *n)
656             {
657             int i;
658              
659 1333859 100         for (i = 0; i < 128; i++) {
660 1333800 100         if (n128_tstbit(n, i)) {
661 16290           return i;
662             }
663             }
664              
665 59           return INT_MAX;
666             }
667              
668             /**
669             * n128_rscan1(): return the index of the most significant set bit.
670             * @n: N128 object.
671             */
672             static int
673 812           n128_rscan1(n128_t *n)
674             {
675             int i;
676              
677 79255 50         for (i = 127; i >= 0; i--) {
678 79255 100         if (n128_tstbit(n, i)) {
679 812           return i;
680             }
681             }
682              
683 0           return INT_MAX;
684             }
685              
686             /**
687             * n128_print_bin(): write an N128 value as a bitstring.
688             * @n: N128 object.
689             * @buf: bitstring buffer.
690             * @ui_only: a boolean indicating whether only the first 32 bits
691             * should be written.
692             *
693             * The buffer is null-terminated on completion, so it must have either
694             * 129 or 33 characters' capacity, depending on the value of @ui_only.
695             */
696             void
697 9           n128_print_bin(n128_t *n, char *buf, int ui_only)
698             {
699             int i;
700             int j;
701              
702 9 100         j = (ui_only) ? 0 : 3;
703              
704 30 100         for (; j >= 0; j--) {
705 693 100         for (i = 31; i >= 0; i--) {
706 672 100         *buf = (n128_tstbit(n, (j * 32) + i) ? '1' : '0');
707 672           ++buf;
708             }
709             }
710 9           *buf = '\0';
711              
712 9           return;
713             }
714              
715             /**
716             * n128_print_hex(): write an N128 value as a hexadecimal string.
717             * @n: N128 object.
718             * @buf: hexadecimal string buffer.
719             *
720             * The buffer is null-terminated on completion. It must have at least
721             * 33 characters' capacity to handle all possible cases.
722             */
723             void
724 7           n128_print_hex(n128_t *n, char *buf)
725             {
726             int byte;
727             int i;
728             static const char *lookup = "0123456789abcdef";
729              
730 103 100         for (i = 0; i < 16; i++) {
731 99           byte = (n->nums[i / 4] >> ((3 - (i % 4)) * 8)) & 0xFF;
732 99 100         if (byte) {
733 3           break;
734             }
735             }
736              
737 7           *buf++ = '0';
738 7           *buf++ = 'x';
739              
740 7 100         if (i == 16) {
741 4           *buf++ = '0';
742             } else {
743 19 100         for (; i < 16; i++) {
744 16           byte = (n->nums[i / 4] >> ((3 - (i % 4)) * 8)) & 0xFF;
745 16           *buf++ = lookup[(byte >> 4) & 0xF];
746 16           *buf++ = lookup[byte & 0xF];
747             }
748             }
749            
750 7           *buf = '\0';
751              
752 7           return;
753             }
754              
755             static int
756 406           n128_divmod_10(n128_t *n, n128_t *qp, n128_t *rp)
757             {
758             n128_t ten;
759             n128_t *tenp;
760             n128_t t;
761             n128_t *tp;
762             n128_t na;
763             n128_t *np;
764             int shift;
765             int shift1;
766             int shift2;
767              
768 406           tenp = &ten;
769 406           tp = &t;
770 406           np = &na;
771 406           n128_set(np, n);
772 406           n128_set_ui(qp, 0);
773              
774 406           n128_set_ui(tenp, 10);
775 406           shift1 = n128_rscan1(np);
776 406           shift2 = n128_rscan1(tenp);
777 406           shift = shift1 - shift2;
778 406 100         if (shift < 0) {
779             /* Divisor is larger than dividend. */
780 23           n128_set_ui(qp, 0);
781 23           n128_set(rp, np);
782 23           return 1;
783             }
784 383           n128_blsft(tenp, shift);
785              
786             while (1) {
787 22682           n128_set(tp, np);
788 22682 100         if (n128_cmp(tp, tenp) >= 0) {
789 11386           n128_sub(tp, tenp);
790 11386           n128_setbit(qp, 0);
791 11386           n128_set(np, tp);
792             }
793 22682 100         if (n128_cmp_ui(tenp, 10) == 0) {
794 383           n128_set(rp, np);
795 383           return 1;
796             }
797 22299           n128_brsft(tenp, 1);
798 22299           n128_blsft(qp, 1);
799 22705           }
800             }
801              
802             /**
803             * n128_print_dec(): write an N128 value as a decimal string.
804             * @n: N128 object.
805             * @buf: decimal string buffer.
806             *
807             * The buffer is null-terminated on completion. It must have at least
808             * 40 characters' capacity to handle all possible cases.
809             */
810             void
811 31           n128_print_dec(n128_t *n, char *buf)
812             {
813 31           int i = 0;
814             int nums[50];
815 31           int nc = 0;
816             n128_t na;
817 31           n128_t *np = &na;
818             n128_t q;
819 31           n128_t *qp = &q;
820             n128_t r;
821 31           n128_t *rp = &r;
822            
823 31           n128_set(np, n);
824 31           n128_set(qp, np);
825              
826 31 100         if (n128_cmp_ui(qp, 0) == 0) {
827 8           *buf++ = '0';
828 8           *buf = '\0';
829 8           return;
830             }
831              
832 429 100         while (n128_cmp_ui(qp, 0) != 0) {
833 406           n128_set(np, qp);
834 406           n128_divmod_10(np, qp, rp);
835 406           nums[nc++] = rp->nums[3];
836             }
837              
838 23           --nc;
839 429 100         for (i = nc; i >= 0; i--) {
840 406           *buf++ = '0' + nums[i];
841             }
842 23           *buf = '\0';
843              
844 31           return;
845             }
846              
847             #ifdef __cplusplus
848             }
849             #endif