D: Convert/parse uint integer to string. (@nogc)
Julian Fondren
julian.fondren at gmail.com
Tue Nov 28 10:36:33 UTC 2023
On Tuesday, 28 November 2023 at 08:51:21 UTC, Mark Davies wrote:
> I did it this way ...
You always print the full array of bytes this way. Output piped
to `od -c` is
```
0000000 1 2 3 4 5 377 377 377 377 377 \n - 1 2
3 4
0000020 5 377 377 377 377 \n
```
Those 377s are `char.init`, 0xFF.
On Tuesday, 28 November 2023 at 09:43:47 UTC, Dom DiSc wrote:
> For a 'long' 10 characters is likely to be not enough (long max
> is 9223372036854775808 which has 19 chars, and you should
> reserve additional one for the sign and one for the terminating
> null), so I would at least recommend using char[21].
Signed max is all bits but the sign bit set, so 7FFF...FFFF, so
signed max is always an odd number. d can confirm:
```
$ rdmd --eval 'writeln(long.max)'
9223372036854775807
$ rdmd --eval 'writeln(2+to!string(long.max).length)'
21
```
There's no terminating NUL here, which might be an oversight.
> with char[10] your function becomes a big hole in your
> security, as it can easily be misused to write 10 bytes of
> freely selectable garbage behind your allocated memory.
This is D though, so without separately disabling bounds checks,
there's an error:
```
core.exception.ArrayIndexError at d1.d(22): index [18] is out of
bounds for array of length 10
```
or with -betterC:
```
d1: d1.d:21: Assertion `array index out of bounds' failed.
Aborted
```
Here's a minimal edit to fix the `char.init` output:
```d
char[] longToString(long n) @nogc
{
static char[21] x;
size_t length;
ulong power;
x[0] = '-'*(n<0);
long t = (n<0)*-n + (n>0)*n ;
while (n != 0)
{
power++;
n /= 10;
}
length = power;
power -= (x[0] != '-');
while (t > 0)
{
x[power] = (t % 10) + '0';
power--;
t /= 10;
}
return x[0 .. length];
}
```
As you can see, slices from this longToString are good until the
next call to it. The other C-like way to manage memory is to pass
in the buffer to use, which in D can be a slice of a static array
on the caller's stack. You'll probably have a much better time
with manual memory management if you use custom allocators.
More information about the Digitalmars-d-learn
mailing list