| 241 | |
| 242 | |
| 243 | struct value_float_t : public value_t { |
| 244 | value val; |
| 245 | value_float_t(double v) { |
| 246 | val_flt = v; |
| 247 | val_int = std::isfinite(v) ? static_cast<int64_t>(v) : 0; |
| 248 | val = mk_val<value_int>(val_int); |
| 249 | } |
| 250 | virtual std::string type() const override { return "Float"; } |
| 251 | virtual double as_float() const override { return val_flt; } |
| 252 | virtual int64_t as_int() const override { return val_int; } |
| 253 | virtual string as_string() const override { |
| 254 | std::string out = std::to_string(val_flt); |
| 255 | out.erase(out.find_last_not_of('0') + 1, std::string::npos); // remove trailing zeros |
| 256 | if (out.back() == '.') out.push_back('0'); // leave one zero if no decimals |
| 257 | return out; |
| 258 | } |
| 259 | virtual bool as_bool() const override { |
| 260 | return val_flt != 0.0; |
| 261 | } |
| 262 | virtual const func_builtins & get_builtins() const override; |
| 263 | virtual bool is_numeric() const override { return true; } |
| 264 | virtual bool is_hashable() const override { return true; } |
| 265 | virtual hasher unique_hash() const noexcept override { |
| 266 | if (static_cast<double>(val_int) == val_flt) { |
| 267 | return val->unique_hash(); |
| 268 | } else { |
| 269 | return hasher(typeid(*this)) |
| 270 | .update(&val_int, sizeof(val_int)) |
| 271 | .update(&val_flt, sizeof(val_flt)); |
| 272 | } |
| 273 | } |
| 274 | protected: |
| 275 | virtual bool equivalent(const value_t & other) const override { |
| 276 | return other.is_numeric() && val_int == other.val_int && val_flt == other.val_flt; |
| 277 | } |
| 278 | virtual bool nonequal(const value_t & other) const override { |
| 279 | return !(typeid(*this) == typeid(other) && val_flt == other.val_flt); |
| 280 | } |
| 281 | }; |
| 282 | using value_float = std::shared_ptr<value_float_t>; |
| 283 | |
| 284 | |