Commit 01323e31 authored by Tyler John Smith's avatar Tyler John Smith Committed by Facebook Github Bot

Fix ordering issue with folly dynamic subtraction and division

Summary:
folly dynamic "double / int" (division, same goes for subtraction) results in the operands switching places (always becomes "int / double") due to int and non-int checking logic.

Same applies to addition and multiplication, but order doesn't matter for those.

If both dynamics are doubles or both are ints, then the problematic logic is bypassed.

So this is only when you have one int and one double, and the int comes second, and the operand is subtraction or division.

Reviewed By: yfeldblum

Differential Revision: D14379896

fbshipit-source-id: e76f1fe677fc4ea69856649ab046a5080a902b0d
parent 3a0d4ce4
......@@ -159,12 +159,7 @@ dynamic numericOp(dynamic const& a, dynamic const& b) {
if (!a.isNumber() || !b.isNumber()) {
throw_exception<TypeError>("numeric", a.type(), b.type());
}
if (a.type() != b.type()) {
auto& integ = a.isInt() ? a : b;
auto& nonint = a.isInt() ? b : a;
return Op<double>()(to<double>(integ.asInt()), nonint.asDouble());
}
if (a.isDouble()) {
if (a.isDouble() || b.isDouble()) {
return Op<double>()(a.asDouble(), b.asDouble());
}
return Op<int64_t>()(a.asInt(), b.asInt());
......
......@@ -1206,3 +1206,48 @@ TEST(Dynamic, JSONPointer) {
EXPECT_EQ(nullptr, target.get_ptr(json_pointer::parse("/foo/-")));
}
}
TEST(Dynamic, Math) {
// tests int-int, int-double, double-int, and double-double math operations
std::vector<dynamic> values = {2, 5.0};
// addition
for (auto value1 : values) {
for (auto value2 : values) {
auto testValue = value1;
testValue += value2;
EXPECT_NEAR(
value1.asDouble() + value2.asDouble(), testValue.asDouble(), 0.0001);
}
}
// subtraction
for (auto value1 : values) {
for (auto value2 : values) {
auto testValue = value1;
testValue -= value2;
EXPECT_NEAR(
value1.asDouble() - value2.asDouble(), testValue.asDouble(), 0.0001);
}
}
// multiplication
for (auto value1 : values) {
for (auto value2 : values) {
auto testValue = value1;
testValue *= value2;
EXPECT_NEAR(
value1.asDouble() * value2.asDouble(), testValue.asDouble(), 0.0001);
}
}
// division
for (auto value1 : values) {
for (auto value2 : values) {
auto testValue = value1;
testValue /= value2;
EXPECT_NEAR(
value1.asDouble() / value2.asDouble(), testValue.asDouble(), 0.0001);
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment