summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2016-08-19 10:13:45 +0200
committerUlf Hermann <ulf.hermann@qt.io>2016-08-23 13:46:22 +0000
commit8b7dbfe1e0c0d4b8d0984fb381f1a0bb6b566e76 (patch)
tree3438c6ec351cc6cadbbacdfd170affd8605e6a44 /src
parent4f0988c3907406087dbfdc193abfbf767678d814 (diff)
V4: Correctly format on Number.toPrecision(n)
The ecmascript standard mandates that we add trailing zeroes if the given precision is greater than the number of digits available. The only way to request this from QLocale is currently QString::asprintf(), which adds a few other incompatibilities that are easier to 'fix' by editing the resulting string. Thus we use it as a stop gap measure until we can expose better API from qtbase. Task-number: QTBUG-55358 Change-Id: Iafc11f21abb341fbe458ad75b46b4222ae5bc1db Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index ab3e03b183..0e653c18cb 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -263,12 +263,30 @@ ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx)
if (!ctx->argc() || ctx->args()[0].isUndefined())
return RuntimeHelpers::toString(scope.engine, v);
- double precision = ctx->args()[0].toInt32();
+ int precision = ctx->args()[0].toInt32();
if (precision < 1 || precision > 21) {
ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range")));
return ctx->engine()->throwRangeError(error);
}
- QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision);
+ // TODO: Once we get a NumberOption to retain trailing zeroes, replace the code below with:
+ // QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision);
+ QByteArray format = "%#." + QByteArray::number(precision) + "g";
+ QString result = QString::asprintf(format.constData(), v->asDouble());
+ if (result.endsWith(QLatin1Char('.'))) {
+ // This is 'f' notation, not 'e'.
+ result.chop(1);
+ } else {
+ int ePos = result.indexOf(QLatin1Char('e'));
+ if (ePos != -1) {
+ Q_ASSERT(ePos + 2 < result.length()); // always '+' or '-', and number, after 'e'
+ Q_ASSERT(ePos > 0); // 'e' is not the first character
+
+ if (result.at(ePos + 2) == QLatin1Char('0')) // Drop leading zeroes in exponent
+ result = result.remove(ePos + 2, 1);
+ if (result.at(ePos - 1) == QLatin1Char('.')) // Drop trailing dots before 'e'
+ result = result.remove(ePos - 1, 1);
+ }
+ }
return scope.engine->newString(result)->asReturnedValue();
}