1 /// High-level wrappers for C-conversion functions. 2 module nxt.cconv; 3 4 /// Returns: `value` as a `string`. 5 void toStringInSink(const double value, 6 scope void delegate(scope const(char)[]) @safe sink, 7 in uint digitCount = 5) 8 @trusted 9 { 10 static immutable digitCountMax = 61; 11 assert(digitCount < digitCountMax); 12 char[3 + digitCountMax] buffer; // (sign + dot + null) and digits 13 gcvt(value, digitCount, buffer.ptr); 14 import core.stdc.string : cstrlen = strlen; 15 sink(buffer[0 .. cstrlen(buffer.ptr)]); /+ TODO: avoid +/ 16 } 17 18 /// Returns: `value` as a `string`. 19 string toString(const double value, 20 in uint digitCount = 30) 21 @trusted pure nothrow 22 { 23 immutable length = 3 + digitCount; // (sign + dot + null) and digits 24 auto buffer = new char[length]; 25 gcvt(value, digitCount, buffer.ptr); 26 import core.stdc.string : cstrlen = strlen; 27 return buffer[0 .. cstrlen(buffer.ptr)]; /+ TODO: avoid +/ 28 } 29 30 /// 31 pure nothrow @safe unittest { 32 assert(0.0.toString(1) == `0`); 33 assert(0.1.toString(2) == `0.1`); 34 35 assert((-1.0).toString(1) == `-1`); 36 assert((-1.0).toString(2) == `-1`); 37 assert((-1.0).toString(3) == `-1`); 38 39 assert(3.14.toString(3) == `3.14`); 40 assert(3.141.toString(1) == `3`); 41 assert(3.141.toString(2) == `3.1`); 42 assert(3.141.toString(3) == `3.14`); 43 assert(3.141.toString(4) == `3.141`); 44 assert(3.141.toString(5) == `3.141`); 45 46 assert(1234567.123456789123456789.toString(7) == `1234567`); 47 assert(1234567.123456789123456789.toString(8) == `1234567.1`); 48 assert(1234567.123456789123456789.toString(9) == `1234567.12`); 49 assert(1234567.123456789123456789.toString(20) == `1234567.1234567892`); 50 } 51 52 private extern(C) pragma(inline, false) { 53 pure nothrow @nogc: 54 char *gcvt(double number, int ndigit, char *buf); 55 }