Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 34 additions & 18 deletions src/core/math.d
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,11 @@ unittest
/*************************************
* Round argument to a specific precision.
*
* D language types specify a minimum precision, not a maximum. The
* `toPrec()` function forces rounding of the argument `f` to the
* precision of the specified floating point type `T`.
* D language types specify only a minimum precision, not a maximum. The
* `toPrec()` function forces rounding of the argument `f` to the precision
* of the specified floating point type `T`.
* The rounding mode used is inevitably target-dependent, but will be done in
* a way to maximize accuracy. In most cases, the default is round-to-nearest.
*
* Params:
* T = precision type to round to
Expand Down Expand Up @@ -206,9 +208,10 @@ T toPrec(T:real)(real f) { pragma(inline, false); return f; }

@safe unittest
{
static float f = 1.1f;
static double d = 1.1;
static real r = 1.1L;
// Test all instantiations work with all combinations of float.
float f = 1.1f;
double d = 1.1;
real r = 1.1L;
f = toPrec!float(f + f);
f = toPrec!float(d + d);
f = toPrec!float(r + r);
Expand All @@ -219,19 +222,32 @@ T toPrec(T:real)(real f) { pragma(inline, false); return f; }
r = toPrec!real(d + d);
r = toPrec!real(r + r);

/+ Uncomment these once compiler support has been added.
// Comparison tests.
bool approxEqual(T)(T lhs, T rhs)
{
return fabs((lhs - rhs) / rhs) <= 1e-2 || fabs(lhs - rhs) <= 1e-5;
}

enum real PIR = 0xc.90fdaa22168c235p-2;
enum double PID = 0x1.921fb54442d18p+1;
enum float PIF = 0x1.921fb6p+1;

assert(toPrec!float(PIR) == PIF);
assert(toPrec!double(PIR) == PID);
assert(toPrec!real(PIR) == PIR);
assert(toPrec!float(PID) == PIF);
assert(toPrec!double(PID) == PID);
assert(toPrec!real(PID) == PID);
assert(toPrec!float(PIF) == PIF);
assert(toPrec!double(PIF) == PIF);
assert(toPrec!real(PIF) == PIF);
+/
static assert(approxEqual(toPrec!float(PIR), PIF));
static assert(approxEqual(toPrec!double(PIR), PID));
static assert(approxEqual(toPrec!real(PIR), PIR));
static assert(approxEqual(toPrec!float(PID), PIF));
static assert(approxEqual(toPrec!double(PID), PID));
static assert(approxEqual(toPrec!real(PID), PID));
static assert(approxEqual(toPrec!float(PIF), PIF));
static assert(approxEqual(toPrec!double(PIF), PIF));
static assert(approxEqual(toPrec!real(PIF), PIF));

assert(approxEqual(toPrec!float(PIR), PIF));
assert(approxEqual(toPrec!double(PIR), PID));
assert(approxEqual(toPrec!real(PIR), PIR));
assert(approxEqual(toPrec!float(PID), PIF));
assert(approxEqual(toPrec!double(PID), PID));
assert(approxEqual(toPrec!real(PID), PID));
assert(approxEqual(toPrec!float(PIF), PIF));
assert(approxEqual(toPrec!double(PIF), PIF));
assert(approxEqual(toPrec!real(PIF), PIF));
}