summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qfloat16.h16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h
index ab480f84f5..acf9220490 100644
--- a/src/corelib/global/qfloat16.h
+++ b/src/corelib/global/qfloat16.h
@@ -172,8 +172,20 @@ inline qfloat16::qfloat16(float f) noexcept
#else
quint32 u;
memcpy(&u, &f, sizeof(quint32));
- b16 = quint16(basetable[(u >> 23) & 0x1ff]
- + ((u & 0x007fffff) >> shifttable[(u >> 23) & 0x1ff]));
+ const quint32 signAndExp = u >> 23;
+ const quint32 base = basetable[signAndExp];
+ const quint32 shift = shifttable[signAndExp];
+ quint32 mantissa = (u & 0x007fffff);
+ if ((signAndExp & 0xff) == 0xff) {
+ if (mantissa) // keep nan from truncating to inf
+ mantissa = qMax(1U << shift, mantissa);
+ } else {
+ mantissa += (1U << (shift - 1)) - 1; // rounding
+ }
+
+ // We use add as the mantissa may overflow causing
+ // the exp part to shift exactly one value.
+ b16 = quint16(base + (mantissa >> shift));
#endif
}
QT_WARNING_POP