more changes
This commit is contained in:
parent
dae3af89d1
commit
d3ffefbe2d
2 changed files with 95 additions and 0 deletions
|
|
@ -150,6 +150,14 @@ namespace graphene { namespace chain {
|
|||
bool operator != ( const price& a, const price& b );
|
||||
asset operator * ( const asset& a, const price& b );
|
||||
|
||||
price operator * ( const price& p, const ratio_type& r );
|
||||
price operator / ( const price& p, const ratio_type& r );
|
||||
|
||||
inline price& operator *= ( price& p, const ratio_type& r )
|
||||
{ return p = p * r; }
|
||||
inline price& operator /= ( price& p, const ratio_type& r )
|
||||
{ return p = p / r; }
|
||||
|
||||
/**
|
||||
* @class price_feed
|
||||
* @brief defines market parameters for margin positions
|
||||
|
|
|
|||
|
|
@ -111,6 +111,93 @@ namespace graphene { namespace chain {
|
|||
return price{base,quote};
|
||||
} FC_CAPTURE_AND_RETHROW( (base)(quote) ) }
|
||||
|
||||
price operator * ( const price& p, const ratio_type& r )
|
||||
{ try {
|
||||
p.validate();
|
||||
|
||||
FC_ASSERT( r.numerator() > 0 && r.denominator() > 0 );
|
||||
|
||||
if( r.numerator() == r.denominator() ) return p;
|
||||
|
||||
boost::rational<int128_t> p128( p.base.amount.value, p.quote.amount.value );
|
||||
boost::rational<int128_t> r128( r.numerator(), r.denominator() );
|
||||
auto cp = p128 * r128;
|
||||
auto ocp = cp;
|
||||
|
||||
bool shrinked = false;
|
||||
bool using_max = false;
|
||||
static const int128_t max( GRAPHENE_MAX_SHARE_SUPPLY );
|
||||
while( cp.numerator() > max || cp.denominator() > max )
|
||||
{
|
||||
if( cp.numerator() == 1 )
|
||||
{
|
||||
cp = boost::rational<int128_t>( 1, max );
|
||||
using_max = true;
|
||||
break;
|
||||
}
|
||||
else if( cp.denominator() == 1 )
|
||||
{
|
||||
cp = boost::rational<int128_t>( max, 1 );
|
||||
using_max = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp = boost::rational<int128_t>( cp.numerator() >> 1, cp.denominator() >> 1 );
|
||||
shrinked = true;
|
||||
}
|
||||
}
|
||||
if( shrinked ) // maybe not accurate enough due to rounding, do additional checks here
|
||||
{
|
||||
int128_t num = ocp.numerator();
|
||||
int128_t den = ocp.denominator();
|
||||
if( num > den )
|
||||
{
|
||||
num /= den;
|
||||
if( num > max )
|
||||
num = max;
|
||||
den = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
den /= num;
|
||||
if( den > max )
|
||||
den = max;
|
||||
num = 1;
|
||||
}
|
||||
boost::rational<int128_t> ncp( num, den );
|
||||
if( num == max || den == max ) // it's on the edge, we know it's accurate enough
|
||||
cp = ncp;
|
||||
else
|
||||
{
|
||||
// from the accurate ocp, now we have ncp and cp. use the one which is closer to ocp.
|
||||
// TODO improve performance
|
||||
auto diff1 = abs( ncp - ocp );
|
||||
auto diff2 = abs( cp - ocp );
|
||||
if( diff1 < diff2 ) cp = ncp;
|
||||
}
|
||||
}
|
||||
|
||||
price np = asset( static_cast<int64_t>(cp.numerator()), p.base.asset_id )
|
||||
/ asset( static_cast<int64_t>(cp.denominator()), p.quote.asset_id );
|
||||
|
||||
if( shrinked || using_max )
|
||||
{
|
||||
if( ( r.numerator() > r.denominator() && np < p )
|
||||
|| ( r.numerator() < r.denominator() && np > p ) )
|
||||
// even with an accurate result, if p is out of valid range, return it
|
||||
np = p;
|
||||
}
|
||||
|
||||
np.validate();
|
||||
return np;
|
||||
} FC_CAPTURE_AND_RETHROW( (p)(r.numerator())(r.denominator()) ) }
|
||||
|
||||
price operator / ( const price& p, const ratio_type& r )
|
||||
{ try {
|
||||
return p * ratio_type( r.denominator(), r.numerator() );
|
||||
} FC_CAPTURE_AND_RETHROW( (p)(r.numerator())(r.denominator()) ) }
|
||||
|
||||
price price::max( asset_id_type base, asset_id_type quote ) { return asset( share_type(GRAPHENE_MAX_SHARE_SUPPLY), base ) / asset( share_type(1), quote); }
|
||||
price price::min( asset_id_type base, asset_id_type quote ) { return asset( 1, base ) / asset( GRAPHENE_MAX_SHARE_SUPPLY, quote); }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue