Log Message
Source/WebCore: [Platform] Introduce conversion from/to Deciaml to/from double https://bugs.webkit.org/show_bug.cgi?id=88480
Reviewed by Kent Tamura. This patch added functions for Decimal/Double conversion and isInfinity for reducing patch size of introducing Decimal arithmetic, bug 88383. Tests: WebKit/chromium/tests/DecimalTest.cpp * platform/Decimal.cpp: (WebCore::Decimal::fromDouble): Added. (WebCore::Decimal::toDouble): Added. * platform/Decimal.h: (WebCore::Decimal::EncodedData::isInfinity): Added for isinf() (WebCore::Decimal::isInfinity): Added. Source/WebKit/chromium: [Platform] Introduce conversion from/to Deciaml to/from double and helper functions https://bugs.webkit.org/show_bug.cgi?id=88480 Reviewed by Kent Tamura. This patch added tests for Decimal::fromDouble, isInfinity, toDouble. * tests/DecimalTest.cpp: (TEST_F):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (119691 => 119692)
--- trunk/Source/WebCore/ChangeLog 2012-06-07 07:45:21 UTC (rev 119691)
+++ trunk/Source/WebCore/ChangeLog 2012-06-07 07:56:57 UTC (rev 119692)
@@ -1,3 +1,22 @@
+2012-06-07 Yoshifumi Inoue <[email protected]>
+
+ [Platform] Introduce conversion from/to Deciaml to/from double
+ https://bugs.webkit.org/show_bug.cgi?id=88480
+
+ Reviewed by Kent Tamura.
+
+ This patch added functions for Decimal/Double conversion and isInfinity
+ for reducing patch size of introducing Decimal arithmetic, bug 88383.
+
+ Tests: WebKit/chromium/tests/DecimalTest.cpp
+
+ * platform/Decimal.cpp:
+ (WebCore::Decimal::fromDouble): Added.
+ (WebCore::Decimal::toDouble): Added.
+ * platform/Decimal.h:
+ (WebCore::Decimal::EncodedData::isInfinity): Added for isinf()
+ (WebCore::Decimal::isInfinity): Added.
+
2012-06-06 Xianzhu Wang <[email protected]>
Element.getBoundingClientRect() and Element.getClientRects() return incorrect values in frames in a scaled page
Modified: trunk/Source/WebCore/platform/Decimal.cpp (119691 => 119692)
--- trunk/Source/WebCore/platform/Decimal.cpp 2012-06-07 07:45:21 UTC (rev 119691)
+++ trunk/Source/WebCore/platform/Decimal.cpp 2012-06-07 07:56:57 UTC (rev 119692)
@@ -37,6 +37,7 @@
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
#include <wtf/Noncopyable.h>
+#include <wtf/dtoa.h>
#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -678,6 +679,19 @@
return Decimal(sign(), 0, result);
}
+Decimal Decimal::fromDouble(double doubleValue)
+{
+ if (isfinite(doubleValue)) {
+ NumberToStringBuffer buffer;
+ return fromString(numberToString(doubleValue, buffer));
+ }
+
+ if (isinf(doubleValue))
+ return infinity(doubleValue < 0 ? Negative : Positive);
+
+ return nan();
+}
+
Decimal Decimal::fromString(const String& str)
{
int exponent = 0;
@@ -916,6 +930,20 @@
return Decimal(sign(), 0, result);
}
+double Decimal::toDouble() const
+{
+ if (isFinite()) {
+ bool valid;
+ const double doubleValue = toString().toDouble(&valid);
+ return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN();
+ }
+
+ if (isInfinity())
+ return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
+
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
String Decimal::toString() const
{
switch (m_data.formatClass()) {
Modified: trunk/Source/WebCore/platform/Decimal.h (119691 => 119692)
--- trunk/Source/WebCore/platform/Decimal.h 2012-06-07 07:45:21 UTC (rev 119691)
+++ trunk/Source/WebCore/platform/Decimal.h 2012-06-07 07:56:57 UTC (rev 119692)
@@ -68,6 +68,7 @@
int countDigits() const;
int exponent() const { return m_exponent; }
bool isFinite() const { return !isSpecial(); }
+ bool isInfinity() const { return m_formatClass == ClassInfinity; }
bool isNaN() const { return m_formatClass == ClassNaN; }
bool isSpecial() const { return m_formatClass == ClassInfinity || m_formatClass == ClassNaN; }
bool isZero() const { return m_formatClass == ClassZero; }
@@ -122,6 +123,7 @@
}
bool isFinite() const { return m_data.isFinite(); }
+ bool isInfinity() const { return m_data.isInfinity(); }
bool isNaN() const { return m_data.isNaN(); }
bool isNegative() const { return sign() == Negative; }
bool isPositive() const { return sign() == Positive; }
@@ -134,9 +136,11 @@
Decimal remainder(const Decimal&) const;
Decimal round() const;
+ double toDouble() const;
// Note: toString method supports infinity and nan but fromString not.
String toString() const;
+ static Decimal fromDouble(double);
// fromString supports following syntax EBNF:
// number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)?
// | sign? '.' digit+ (exponent-marker sign? digit+)?
Modified: trunk/Source/WebKit/chromium/ChangeLog (119691 => 119692)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-06-07 07:45:21 UTC (rev 119691)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-06-07 07:56:57 UTC (rev 119692)
@@ -1,3 +1,15 @@
+2012-06-07 Yoshifumi Inoue <[email protected]>
+
+ [Platform] Introduce conversion from/to Deciaml to/from double and helper functions
+ https://bugs.webkit.org/show_bug.cgi?id=88480
+
+ Reviewed by Kent Tamura.
+
+ This patch added tests for Decimal::fromDouble, isInfinity, toDouble.
+
+ * tests/DecimalTest.cpp:
+ (TEST_F):
+
2012-06-07 Ami Fischman <[email protected]>
Unreviewed. Rolled DEPS.
Modified: trunk/Source/WebKit/chromium/tests/DecimalTest.cpp (119691 => 119692)
--- trunk/Source/WebKit/chromium/tests/DecimalTest.cpp 2012-06-07 07:45:21 UTC (rev 119691)
+++ trunk/Source/WebKit/chromium/tests/DecimalTest.cpp 2012-06-07 07:56:57 UTC (rev 119692)
@@ -556,6 +556,32 @@
EXPECT_EQ(Decimal::nan(), Decimal::nan().floor());
}
+TEST_F(DecimalTest, FromDouble)
+{
+ EXPECT_EQ(encode(0, 0, Positive), Decimal::fromDouble(0.0));
+ EXPECT_EQ(encode(0, 0, Negative), Decimal::fromDouble(-0.0));
+ EXPECT_EQ(encode(1, 0, Positive), Decimal::fromDouble(1));
+ EXPECT_EQ(encode(1, 0, Negative), Decimal::fromDouble(-1));
+ EXPECT_EQ(encode(123, 0, Positive), Decimal::fromDouble(123));
+ EXPECT_EQ(encode(123, 0, Negative), Decimal::fromDouble(-123));
+ EXPECT_EQ(encode(1, -1, Positive), Decimal::fromDouble(0.1));
+ EXPECT_EQ(encode(1, -1, Negative), Decimal::fromDouble(-0.1));
+}
+
+TEST_F(DecimalTest, FromDoubleLimits)
+{
+ EXPECT_EQ(encode(UINT64_C(2220446049250313), -31, Positive), Decimal::fromDouble(std::numeric_limits<double>::epsilon()));
+ EXPECT_EQ(encode(UINT64_C(2220446049250313), -31, Negative), Decimal::fromDouble(-std::numeric_limits<double>::epsilon()));
+ EXPECT_EQ(encode(UINT64_C(17976931348623157), 292, Positive), Decimal::fromDouble(std::numeric_limits<double>::max()));
+ EXPECT_EQ(encode(UINT64_C(17976931348623157), 292, Negative), Decimal::fromDouble(-std::numeric_limits<double>::max()));
+ EXPECT_EQ(encode(UINT64_C(22250738585072014), -324, Positive), Decimal::fromDouble(std::numeric_limits<double>::min()));
+ EXPECT_EQ(encode(UINT64_C(22250738585072014), -324, Negative), Decimal::fromDouble(-std::numeric_limits<double>::min()));
+ EXPECT_TRUE(Decimal::fromDouble(std::numeric_limits<double>::infinity()).isInfinity());
+ EXPECT_TRUE(Decimal::fromDouble(-std::numeric_limits<double>::infinity()).isInfinity());
+ EXPECT_TRUE(Decimal::fromDouble(std::numeric_limits<double>::quiet_NaN()).isNaN());
+ EXPECT_TRUE(Decimal::fromDouble(-std::numeric_limits<double>::quiet_NaN()).isNaN());
+}
+
TEST_F(DecimalTest, FromInt32)
{
EXPECT_EQ(encode(0, 0, Positive), Decimal(0));
@@ -750,24 +776,32 @@
TEST_F(DecimalTest, Predicates)
{
EXPECT_TRUE(Decimal::zero(Positive).isFinite());
+ EXPECT_FALSE(Decimal::zero(Positive).isInfinity());
+ EXPECT_FALSE(Decimal::zero(Positive).isNaN());
EXPECT_TRUE(Decimal::zero(Positive).isPositive());
EXPECT_FALSE(Decimal::zero(Positive).isNegative());
EXPECT_FALSE(Decimal::zero(Positive).isSpecial());
EXPECT_TRUE(Decimal::zero(Positive).isZero());
EXPECT_TRUE(Decimal::zero(Negative).isFinite());
+ EXPECT_FALSE(Decimal::zero(Negative).isInfinity());
+ EXPECT_FALSE(Decimal::zero(Negative).isNaN());
EXPECT_FALSE(Decimal::zero(Negative).isPositive());
EXPECT_TRUE(Decimal::zero(Negative).isNegative());
EXPECT_FALSE(Decimal::zero(Negative).isSpecial());
EXPECT_TRUE(Decimal::zero(Negative).isZero());
EXPECT_TRUE(Decimal(123).isFinite());
+ EXPECT_FALSE(Decimal(123).isInfinity());
+ EXPECT_FALSE(Decimal(123).isNaN());
EXPECT_TRUE(Decimal(123).isPositive());
EXPECT_FALSE(Decimal(123).isNegative());
EXPECT_FALSE(Decimal(123).isSpecial());
EXPECT_FALSE(Decimal(123).isZero());
EXPECT_TRUE(Decimal(-123).isFinite());
+ EXPECT_FALSE(Decimal(-123).isInfinity());
+ EXPECT_FALSE(Decimal(-123).isNaN());
EXPECT_FALSE(Decimal(-123).isPositive());
EXPECT_TRUE(Decimal(-123).isNegative());
EXPECT_FALSE(Decimal(-123).isSpecial());
@@ -777,18 +811,24 @@
TEST_F(DecimalTest, PredicatesSpecialValues)
{
EXPECT_FALSE(Decimal::infinity(Positive).isFinite());
+ EXPECT_TRUE(Decimal::infinity(Positive).isInfinity());
+ EXPECT_FALSE(Decimal::infinity(Positive).isNaN());
EXPECT_TRUE(Decimal::infinity(Positive).isPositive());
EXPECT_FALSE(Decimal::infinity(Positive).isNegative());
EXPECT_TRUE(Decimal::infinity(Positive).isSpecial());
EXPECT_FALSE(Decimal::infinity(Positive).isZero());
EXPECT_FALSE(Decimal::infinity(Negative).isFinite());
+ EXPECT_TRUE(Decimal::infinity(Negative).isInfinity());
+ EXPECT_FALSE(Decimal::infinity(Negative).isNaN());
EXPECT_FALSE(Decimal::infinity(Negative).isPositive());
EXPECT_TRUE(Decimal::infinity(Negative).isNegative());
EXPECT_TRUE(Decimal::infinity(Negative).isSpecial());
EXPECT_FALSE(Decimal::infinity(Negative).isZero());
EXPECT_FALSE(Decimal::nan().isFinite());
+ EXPECT_FALSE(Decimal::nan().isInfinity());
+ EXPECT_TRUE(Decimal::nan().isNaN());
EXPECT_TRUE(Decimal::nan().isSpecial());
EXPECT_FALSE(Decimal::nan().isZero());
}
@@ -940,6 +980,42 @@
EXPECT_EQ(NaN, MinusInfinity - NaN);
}
+TEST_F(DecimalTest, ToDouble)
+{
+ EXPECT_EQ(0.0, encode(0, 0, Positive).toDouble());
+ EXPECT_EQ(-0.0, encode(0, 0, Negative).toDouble());
+
+ EXPECT_EQ(1.0, encode(1, 0, Positive).toDouble());
+ EXPECT_EQ(-1.0, encode(1, 0, Negative).toDouble());
+
+ EXPECT_EQ(0.1, encode(1, -1, Positive).toDouble());
+ EXPECT_EQ(-0.1, encode(1, -1, Negative).toDouble());
+ EXPECT_EQ(0.3, encode(3, -1, Positive).toDouble());
+ EXPECT_EQ(-0.3, encode(3, -1, Negative).toDouble());
+ EXPECT_EQ(0.6, encode(6, -1, Positive).toDouble());
+ EXPECT_EQ(-0.6, encode(6, -1, Negative).toDouble());
+ EXPECT_EQ(0.7, encode(7, -1, Positive).toDouble());
+ EXPECT_EQ(-0.7, encode(7, -1, Negative).toDouble());
+
+ EXPECT_EQ(0.01, encode(1, -2, Positive).toDouble());
+ EXPECT_EQ(0.001, encode(1, -3, Positive).toDouble());
+ EXPECT_EQ(0.0001, encode(1, -4, Positive).toDouble());
+ EXPECT_EQ(0.00001, encode(1, -5, Positive).toDouble());
+
+ EXPECT_EQ(1e+308, encode(1, 308, Positive).toDouble());
+ EXPECT_EQ(1e-307, encode(1, -307, Positive).toDouble());
+
+ EXPECT_TRUE(isinf(encode(1, 1000, Positive).toDouble()));
+ EXPECT_EQ(0.0, encode(1, -1000, Positive).toDouble());
+}
+
+TEST_F(DecimalTest, ToDoubleSpecialValues)
+{
+ EXPECT_TRUE(isinf(Decimal::infinity(Decimal::Positive).toDouble()));
+ EXPECT_TRUE(isinf(Decimal::infinity(Decimal::Negative).toDouble()));
+ EXPECT_TRUE(isnan(Decimal::nan().toDouble()));
+}
+
TEST_F(DecimalTest, ToString)
{
EXPECT_EQ(String("0"), Decimal::zero(Positive).toString());
_______________________________________________ webkit-changes mailing list [email protected] http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes
