diff --git a/source/maths/Fixed.h b/source/maths/Fixed.h index 859fba99c3..b1f170891d 100644 --- a/source/maths/Fixed.h +++ b/source/maths/Fixed.h @@ -92,6 +92,12 @@ inline T round_away_from_zero(float value) return (T)(value >= 0 ? value + 0.5f : value - 0.5f); } +template +inline T round_away_from_zero(double value) +{ + return (T)(value >= 0 ? value + 0.5 : value - 0.5); +} + /** * A simple fixed-point number class. * diff --git a/source/scriptinterface/tests/test_ScriptConversions.h b/source/scriptinterface/tests/test_ScriptConversions.h index d47af09390..a9154f9e45 100644 --- a/source/scriptinterface/tests/test_ScriptConversions.h +++ b/source/scriptinterface/tests/test_ScriptConversions.h @@ -47,7 +47,7 @@ class TestScriptConversions : public CxxTest::TestSuite } template - void roundtrip(const T& value, const std::string& expected) + void roundtrip(const T& value, const char* expected) { ScriptInterface script("Test"); JSContext* cx = script.GetContext(); @@ -58,7 +58,8 @@ class TestScriptConversions : public CxxTest::TestSuite std::string source; TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalObject(cx)), "uneval", CScriptVal(v1), source)); - TS_ASSERT_STR_EQUALS(source, expected); + if (expected) + TS_ASSERT_STR_EQUALS(source, expected); T v2 = T(); TS_ASSERT(ScriptInterface::FromJSVal(script.GetContext(), v1, v2)); @@ -160,4 +161,23 @@ public: } // TODO: test vectors + + void test_fixed() + { + // NOTE: fixed conversions are defined in simulation2/scripting/EngineScriptConversions.cpp + + fixed f; + + f.SetInternalValue(10590283); + roundtrip(f, "161.5948944091797"); + + f.SetInternalValue(-10590283); + roundtrip(f, "-161.5948944091797"); + + f.SetInternalValue(2000000000); + roundtrip(f, "30517.578125"); + + f.SetInternalValue(2000000001); + roundtrip(f, "30517.57814025879"); + } }; diff --git a/source/simulation2/scripting/EngineScriptConversions.cpp b/source/simulation2/scripting/EngineScriptConversions.cpp index 95d9e8458c..0053dc97ca 100644 --- a/source/simulation2/scripting/EngineScriptConversions.cpp +++ b/source/simulation2/scripting/EngineScriptConversions.cpp @@ -186,7 +186,8 @@ template<> bool ScriptInterface::FromJSVal(JSContext* cx, jsval v, fixed& if (!JS_ValueToNumber(cx, v, &ret)) return false; out = fixed::FromDouble(ret); - // TODO: ought to check that this conversion is consistent and portable + // double can precisely represent the full range of fixed, so this is a non-lossy conversion + return true; } @@ -194,7 +195,6 @@ template<> jsval ScriptInterface::ToJSVal(JSContext* cx, const fixed& val { jsval rval = JSVAL_VOID; JS_NewNumberValue(cx, val.ToDouble(), &rval); // ignore return value - // TODO: ought to check that this conversion is consistent and portable return rval; }