summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2023-08-03 20:52:43 +0200
committerEike Rathke <erack@redhat.com>2023-08-03 21:42:53 +0200
commit46e672db8002e7aaac881bee65b5c50c4e14c666 (patch)
tree758f9727bc22b057dc4054d61c2dfc51316f31e5 /tools
parent0b5e88bc88df6f0cd47e84cbd8bc53b649678f8b (diff)
Resolves: tdf#127334 Increase tools::Duration accuracy epsilon unsharpness
... when converting from double, i.e. to 300 nanoseconds. Empirically determined.. Change-Id: I92c43b5f244923363af5d44bece9c155126ca343 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155324 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Jenkins
Diffstat (limited to 'tools')
-rw-r--r--tools/source/datetime/duration.cxx25
1 files changed, 14 insertions, 11 deletions
diff --git a/tools/source/datetime/duration.cxx b/tools/source/datetime/duration.cxx
index a7b2762fff49..a655f016a1bc 100644
--- a/tools/source/datetime/duration.cxx
+++ b/tools/source/datetime/duration.cxx
@@ -47,8 +47,9 @@ Duration::Duration(const Time& rStart, const Time& rEnd)
}
}
-Duration::Duration(double fTimeInDays)
+Duration::Duration(double fTimeInDays, sal_uInt64 nAccuracyEpsilonNanoseconds)
{
+ assert(nAccuracyEpsilonNanoseconds <= Time::nanoSecPerSec - 1);
double fInt, fFrac;
if (fTimeInDays < 0.0)
{
@@ -66,19 +67,21 @@ Duration::Duration(double fTimeInDays)
fFrac *= Time::nanoSecPerDay;
fFrac = ::rtl::math::approxFloor(fFrac);
sal_Int64 nNS = static_cast<sal_Int64>(fFrac);
- // Round by 1 nanosecond if it's just 1 off to a second, i.e.
- // 0999999999 or 0000000001. This could be loosened to rounding by 2 or
- // such if necessary.
const sal_Int64 nN = nNS % Time::nanoSecPerSec;
- if (std::abs(nN) == 1)
- nNS -= (nNS < 0) ? -1 : 1;
- else if (std::abs(nN) == Time::nanoSecPerSec - 1)
+ if (nN)
{
- nNS += (nNS < 0) ? -1 : 1;
- if (std::abs(nNS) >= Time::nanoSecPerDay)
+ const sal_uInt64 nA = std::abs(nN);
+ if (nA <= nAccuracyEpsilonNanoseconds)
+ nNS -= (nNS < 0) ? -nN : nN;
+ else if (nA >= Time::nanoSecPerSec - nAccuracyEpsilonNanoseconds)
{
- mnDays += nNS / Time::nanoSecPerDay;
- nNS %= Time::nanoSecPerDay;
+ const sal_Int64 nD = Time::nanoSecPerSec - nA;
+ nNS += (nNS < 0) ? -nD : nD;
+ if (std::abs(nNS) >= Time::nanoSecPerDay)
+ {
+ mnDays += nNS / Time::nanoSecPerDay;
+ nNS %= Time::nanoSecPerDay;
+ }
}
}
maTime.MakeTimeFromNS(nNS);