diff --git a/src/common.h b/src/common.h index cae07bc8..56aff1bd 100644 --- a/src/common.h +++ b/src/common.h @@ -101,6 +101,10 @@ struct NumberTraits<4> { static int_t stoi(Args&&... args) { return std::stoi(std::forward(args)...); } template static float_t stof(Args&&... args) { return std::stof(std::forward(args)...); } + + static constexpr int_t c0 = 0b00000000011111111111111111111100; + static constexpr int_t c1 = 0b11111111111111111111111111111100; + static constexpr int_t c2 = 0b00000000000000000000000000000011; }; template <> @@ -112,6 +116,10 @@ struct NumberTraits<8> { static int_t stoi(Args&&... args) { return std::stoll(std::forward(args)...); } template static float_t stof(Args&&... args) { return std::stod(std::forward(args)...); } + + static constexpr int_t c0 = 0b0000000000001111111111111111111111111111111111111111111111111100; + static constexpr int_t c1 = 0b1111111111111111111111111111111111111111111111111111111111111100; + static constexpr int_t c2 = 0b0000000000000000000000000000000000000000000000000000000000000011; }; using Number = NumberTraits; diff --git a/src/pocketpy.h b/src/pocketpy.h index bf9e1891..ef0a535a 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -343,7 +343,7 @@ inline void init_builtins(VM* _vm) { f64 val = _CAST(f64, obj); if(std::isinf(val) || std::isnan(val)) return VAR(std::to_string(val)); std::stringstream ss; - ss << std::setprecision(std::numeric_limits::max_digits10-1-2) << val; + ss << std::setprecision(std::numeric_limits::max_digits10-2) << val; std::string s = ss.str(); if(std::all_of(s.begin()+1, s.end(), isdigit)) s += ".0"; return VAR(s); diff --git a/src/vm.h b/src/vm.h index 884a1728..02b59cc7 100644 --- a/src/vm.h +++ b/src/vm.h @@ -709,24 +709,20 @@ PY_CAST_INT(unsigned long long) template<> inline float py_cast(VM* vm, PyObject* obj){ vm->check_float(obj); - i64 bits = BITS(obj); - bits = (bits >> 2) << 2; + i64 bits = BITS(obj) & Number::c1; return BitsCvt(bits)._float; } template<> inline float _py_cast(VM* vm, PyObject* obj){ - i64 bits = BITS(obj); - bits = (bits >> 2) << 2; + i64 bits = BITS(obj) & Number::c1; return BitsCvt(bits)._float; } template<> inline double py_cast(VM* vm, PyObject* obj){ vm->check_float(obj); - i64 bits = BITS(obj); - bits = (bits >> 2) << 2; + i64 bits = BITS(obj) & Number::c1; return BitsCvt(bits)._float; } template<> inline double _py_cast(VM* vm, PyObject* obj){ - i64 bits = BITS(obj); - bits = (bits >> 2) << 2; + i64 bits = BITS(obj) & Number::c1; return BitsCvt(bits)._float; } @@ -752,11 +748,17 @@ PY_VAR_INT(unsigned int) PY_VAR_INT(unsigned long) PY_VAR_INT(unsigned long long) -#define PY_VAR_FLOAT(T) \ + +#define PY_VAR_FLOAT(T) \ inline PyObject* py_var(VM* vm, T _val){ \ - f64 val = static_cast(_val); \ - i64 bits = BitsCvt(val)._int; \ - bits = (bits >> 2) << 2; \ + BitsCvt val(static_cast(_val)); \ + i64 bits = val._int & Number::c1; \ + i64 tail = val._int & Number::c2; \ + if(tail == 0b10){ \ + if((bits&Number::c0)!=Number::c0 && (bits&0b100)) bits += 0b100; \ + }else if(tail == 0b11){ \ + if((bits&Number::c0)!=Number::c0) bits += 0b100; \ + } \ bits |= 0b10; \ return reinterpret_cast(bits); \ }