diff options
Diffstat (limited to 'fxjse/value.cpp')
-rw-r--r-- | fxjse/value.cpp | 47 |
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); |