/** * Assuming a.type is either the numerator.type or denominator.type in * the price equation, return the number of the other asset type that * could be exchanged at price p. * * ie: p = 3 usd/bts & a = 4 bts then result = 12 usd * ie: p = 3 usd/bts & a = 4 usd then result = 1.333 bts */ asset operator * ( const asset& a, const price& p ) { try { if( a.asset_id == p.base_asset_id ) { fc::bigint ba( a.amount ); // 64.64 fc::bigint r( p.ratio ); // 64.64 auto amnt = ba * r; // 128.128 amnt /= BTS_PRICE_PRECISION; // 128.64 auto lg2 = amnt.log2(); if( lg2 >= 128 ) { FC_THROW_EXCEPTION( addition_overflow, "overflow ${a} * ${p}", ("a",a)("p",p) ); } asset rtn; rtn.amount = amnt.to_int64(); rtn.asset_id = p.quote_asset_id; ilog( "${a} * ${p} => ${rtn}", ("a", a)("p",p )("rtn",rtn) ); return rtn; } else if( a.asset_id == p.quote_asset_id ) { fc::bigint amt( a.amount ); // 64.64 amt *= BTS_PRICE_PRECISION; //<<= 64; // 64.128 fc::bigint pri( p.ratio ); // 64.64 auto result = amt / pri; // 64.64 // ilog( "amt: ${amt} / ${pri}", ("amt",string(amt))("pri",string(pri) ) ); // ilog( "${r}", ("r",string(result) ) ); auto lg2 = result.log2(); if( lg2 >= 128 ) { // wlog( "." ); FC_THROW_EXCEPTION( addition_overflow, "overflow ${a} / ${p} = ${r} lg2 = ${l}", ("a",a)("p",p)("r", std::string(result) )("l",lg2) ); } // result += 5000000000; // TODO: evaluate this rounding factor.. asset r; r.amount = result.to_int64(); r.asset_id = p.base_asset_id; ilog( "r.amount = ${r}", ("r",r.amount) ); ilog( "${a} * ${p} => ${rtn}", ("a", a)("p",p )("rtn",r) ); return r; } FC_THROW_EXCEPTION( asset_type_mismatch, "type mismatch multiplying asset ${a} by price ${p}", ("a",a)("p",p) ); } FC_RETHROW_EXCEPTIONS( warn, "type mismatch multiplying asset ${a} by price ${p}", ("a",a)("p",p) ); }
static inline boost::int64_t to_int64(T1 high, T2 mid1, T3 mid2, T4 mid3, T5 mid4, T6 mid5, T7 mid6, T8 low) { return to_int64(static_cast<unsigned char>(high), static_cast<unsigned char>(mid1), static_cast<unsigned char>(mid2), static_cast<unsigned char>(mid3), static_cast<unsigned char>(mid4), static_cast<unsigned char>(mid5), static_cast<unsigned char>(mid6), static_cast<unsigned char>(low)); }
uint64_t difficulty( const fc::sha224& hash_value ) { if( hash_value == fc::sha224() ) return uint64_t(-1); // div by 0 auto dif = max224() / fc::bigint( (char*)&hash_value, sizeof(hash_value) ); int64_t tmp = dif.to_int64(); // possible if hash_value starts with 1 if( tmp < 0 ) tmp = 0; return tmp; }
int64_t variant::as_int64()const { switch( get_type() ) { case string_type: return to_int64(**reinterpret_cast<const const_string_ptr*>(this)); case double_type: return int64_t(*reinterpret_cast<const double*>(this)); case int64_type: return *reinterpret_cast<const int64_t*>(this); case uint64_type: return int64_t(*reinterpret_cast<const uint64_t*>(this)); case bool_type: return *reinterpret_cast<const bool*>(this); case null_type: return 0; default: FC_THROW_EXCEPTION( bad_cast_exception, "Invalid cast from ${type} to int64", ("type", get_type()) ); } }
variant number_from_stream( T& in ) { fc::stringstream ss; bool dot = false; bool neg = false; if( in.peek() == '-') { neg = true; ss.put( in.get() ); } bool done = false; try { char c; while((c = in.peek()) && !done) { switch( c ) { case '.': if (dot) FC_THROW_EXCEPTION(parse_error_exception, "Can't parse a number with two decimal places"); dot = true; FALLTHROUGH case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ss.put( in.get() ); break; default: if( isalnum( c ) ) { return ss.str() + stringFromToken( in ); } done = true; break; } } } catch (fc::eof_exception&) { // EOF ends the loop } catch (const std::ios_base::failure&) { // read error ends the loop } std::string str = ss.str(); if (str == "-." || str == "." || str == "-") // check the obviously wrong things we could have encountered FC_THROW_EXCEPTION(parse_error_exception, "Can't parse token \"${token}\" as a JSON numeric constant", ("token", str)); if( dot ) return #ifdef WITH_EXOTIC_JSON_PARSERS parser_type == json::legacy_parser_with_string_doubles ? variant(str) : #endif variant(to_double(str)); if( neg ) return to_int64(str); return to_uint64(str); }
inline bool to_int64(string const & s, int64_t & i) { return to_int64(s.c_str(), i); }
inline bool is_number(string const & s) { int64_t dummy; return to_int64(s.c_str(), dummy); }
constexpr #endif uint64_t to_int64(const char (&a)[N]) { return to_int64(a, N-1); }
/// Convert a string to an integer value /// \code /// std::cout << to_int64("\1\2") << std::endl; /// output: 258 // I.e. (1 << 8 | 2) /// \endcode constexpr uint64_t to_int64(const char* a_str, size_t sz) { return sz ? (to_int64(a_str, sz-1) << 8 | (uint8_t)a_str[sz-1]) : 0; }
static inline boost::int64_t to_int64(const Byte *buf) { return to_int64(buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); }
column::operator int64_t() const { return to_int64(); }