25 #include <boost/rational.hpp>
26 #include <boost/multiprecision/cpp_int.hpp>
31 namespace graphene {
namespace protocol {
42 return amult == bmult;
74 FC_THROW_EXCEPTION( fc::assert_exception,
"invalid asset * price", (
"asset",a)(
"price",b) );
79 const asset& a = *
this;
97 "invalid asset::multiply_and_round_up(price)", (
"asset",a)(
"price",b) );
103 return price{base,quote};
116 FC_ASSERT( r.numerator() > 0 && r.denominator() > 0 );
118 if( r.numerator() == r.denominator() )
return p;
121 boost::rational<uint128_t> r128( r.numerator(), r.denominator() );
122 auto cp = p128 * r128;
125 bool shrinked =
false;
126 bool using_max =
false;
128 while( cp.numerator() > max || cp.denominator() > max )
130 if( 1 == cp.numerator() )
132 cp = boost::rational<uint128_t>( 1, max );
136 else if( 1 == cp.denominator() )
138 cp = boost::rational<uint128_t>( max, 1 );
144 cp = boost::rational<uint128_t>( cp.numerator() >> 1, cp.denominator() >> 1 );
150 uint128_t num = ocp.numerator();
151 uint128_t den = ocp.denominator();
152 FC_ASSERT( num > 0 && den > 0,
"Internal error" );
156 num = std::min( num, max );
162 den = std::min( den, max );
165 boost::rational<uint128_t> ncp( num, den );
166 if( num == max || den == max )
172 auto diff1 = (ncp >= ocp) ? (ncp - ocp) : (ocp - ncp);
173 auto diff2 = (cp >= ocp) ? (cp - ocp) : (ocp - cp);
174 if( diff1 < diff2 ) cp = ncp;
181 if( shrinked || using_max )
183 bool flipped = ( r.numerator() > r.denominator() ) ? ( np < p ) : ( np > p );
195 return p *
ratio_type( r.denominator(), r.numerator() );
220 auto cp = swan * ratio;
223 cp = boost::rational<uint128_t>( (cp.numerator() >> 1)+1, (cp.denominator() >> 1)+1 );
225 return (
asset(
static_cast<int64_t
>(cp.denominator()), collateral.
asset_id )
226 /
asset(
static_cast<int64_t
>(cp.numerator()), debt.
asset_id ) );
240 if( check_upper_bound )
243 "Base amount should not be greater than ${max}",
246 "Quote amount should not be greater than ${max}",
287 auto cp = sp * ratio;
290 cp = boost::rational<uint128_t>( (cp.numerator() >> 1)+(cp.numerator()&1U),
291 (cp.denominator() >> 1)+(cp.denominator()&1U) );
316 const uint16_t mcfr = maybe_mcfr.
valid() ? *maybe_mcfr : 0;
328 auto numerator = get_margin_call_price_numerator( maybe_mcfr );
336 auto numerator = get_margin_call_price_numerator( maybe_mcfr );
354 static constexpr int64_t
v = 10 *
p10<N-1>
::v;
360 static constexpr int64_t
v = 1;
366 static constexpr std::array<int64_t, 19> scaled_precision_lut =
375 return scaled_precision_lut[ precision ];