Formatting -0.0 as 0.0
Bastiaan Veelo
Bastiaan at Veelo.net
Mon Oct 18 11:58:36 UTC 2021
On Friday, 15 October 2021 at 14:09:32 UTC, Steven Schveighoffer
wrote:
> The only way I can think of that isn't really intrusive (like
> your `posZero` thing) is to define your own `writef`/`format`
> wrappers (what I'd do is check any doubles, and replace them
> when necessary).
I have settled on a wrapper. @kinke has helped me to deal with
fast-math, so this can be branchless.
```d
import std.traits : isSomeChar, isSomeString;
/** Wraps std.format.format converting any negative zero floating
point to positive. */
immutable(Char)[] fmt(Char, Args...)(in Char[] spec, Args args)
if (isSomeChar!Char)
{
import std.format : format;
return format(spec, PosZero!args);
}
/** idem */
typeof(spec) fmt(alias spec, Args...)(Args args)
if (isSomeString!(typeof(spec)))
{
import std.format : format;
return format!spec(PosZero!args);
}
// Maps args, adding 0.0 if floating point.
private template PosZero(args...)
{
import std.meta : staticMap;
template posZero(alias arg)
{
import std.traits : isFloatingPoint;
static if (isFloatingPoint!(typeof(arg)))
{
version (LDC)
{
import ldc.attributes : llvmFastMathFlag;
@llvmFastMathFlag("clear") auto posZero() {return
arg + 0.0;}
}
else
auto posZero() {return arg + 0.0;}
}
else
alias posZero = arg;
}
alias PosZero = staticMap!(posZero, args);
}
unittest
{
import std.format : format;
//assert((-0.0).format!"%3.1f" == "-0.0");
assert((-0.0).fmt!"%3.1f" == "0.0");
//assert(format("%3.1f", -0.0) == "-0.0");
assert(fmt("%3.1f", -0.0) == "0.0");
string foo(immutable double d)
{
return d.fmt!"%3.1f";
}
assert(foo(-0.0) == "0.0");
//assert(format!"%d;%3.1f;%3.1f;%3.1f;%s"(42, -0.0, 3.14,
-0.0, "!") == "42;-0.0;3.1;-0.0;!");
assert(fmt!"%d;%3.1f;%3.1f;%3.1f;%s"(42, -0.0, 3.14, -0.0f,
"!") == "42;0.0;3.1;0.0;!");
//assert(format("%d;%3.1f;%3.1f;%3.1f;%s", 42, -0.0, 3.14,
-0.0, "!") == "42;-0.0;3.1;-0.0;!");
assert(fmt("%d;%3.1f;%3.1f;%3.1f;%s", 42, -0.0, 3.14, -0.0f,
"!") == "42;0.0;3.1;0.0;!");
assert(fmt!""() == format!""());
assert(fmt("") == format(""));
}
```
Love this language!
-- Bastiaan.
More information about the Digitalmars-d
mailing list