summaryrefslogtreecommitdiff
path: root/fxjse/value.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fxjse/value.cpp')
-rw-r--r--fxjse/value.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/fxjse/value.cpp b/fxjse/value.cpp
index a49ee312f3..743169dd7b 100644
--- a/fxjse/value.cpp
+++ b/fxjse/value.cpp
@@ -11,6 +11,47 @@
#include "fxjse/context.h"
#include "fxjse/include/cfxjse_class.h"
+namespace {
+
+double FXJSE_ftod(FX_FLOAT fNumber) {
+ static_assert(sizeof(FX_FLOAT) == 4, "FX_FLOAT of incorrect size");
+
+ uint32_t nFloatBits = (uint32_t&)fNumber;
+ uint8_t nExponent = (uint8_t)(nFloatBits >> 23);
+ if (nExponent == 0 || nExponent == 255)
+ return fNumber;
+
+ int8_t nErrExp = nExponent - 150;
+ if (nErrExp >= 0)
+ return fNumber;
+
+ double dwError = pow(2.0, nErrExp), dwErrorHalf = dwError / 2;
+ double dNumber = fNumber, dNumberAbs = fabs(fNumber);
+ double dNumberAbsMin = dNumberAbs - dwErrorHalf,
+ dNumberAbsMax = dNumberAbs + dwErrorHalf;
+ int32_t iErrPos = 0;
+ if (floor(dNumberAbsMin) == floor(dNumberAbsMax)) {
+ dNumberAbsMin = fmod(dNumberAbsMin, 1.0);
+ dNumberAbsMax = fmod(dNumberAbsMax, 1.0);
+ int32_t iErrPosMin = 1, iErrPosMax = 38;
+ do {
+ int32_t iMid = (iErrPosMin + iErrPosMax) / 2;
+ double dPow = pow(10.0, iMid);
+ if (floor(dNumberAbsMin * dPow) == floor(dNumberAbsMax * dPow)) {
+ iErrPosMin = iMid + 1;
+ } else {
+ iErrPosMax = iMid;
+ }
+ } while (iErrPosMin < iErrPosMax);
+ iErrPos = iErrPosMax;
+ }
+ double dPow = pow(10.0, iErrPos);
+ return fNumber < 0 ? ceil(dNumber * dPow - 0.5) / dPow
+ : floor(dNumber * dPow + 0.5) / dPow;
+}
+
+} // namespace
+
void FXJSE_ThrowMessage(const CFX_ByteStringC& utf8Message) {
v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
ASSERT(pIsolate);
@@ -77,6 +118,12 @@ void CFXJSE_Value::SetDate(double dDouble) {
m_hValue.Reset(m_pIsolate, hDate);
}
+void CFXJSE_Value::SetFloat(FX_FLOAT fFloat) {
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> pValue = v8::Number::New(m_pIsolate, FXJSE_ftod(fFloat));
+ m_hValue.Reset(m_pIsolate, pValue);
+}
+
FX_BOOL CFXJSE_Value::SetObjectProperty(const CFX_ByteStringC& szPropName,
CFXJSE_Value* lpPropValue) {
ASSERT(lpPropValue);