fix fixed point math
This commit is contained in:
parent
2b76b6d5fe
commit
ec9e85d268
3 changed files with 36 additions and 10 deletions
|
|
@ -10,8 +10,8 @@ namespace fc {
|
||||||
class real128
|
class real128
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
real128( uint64_t integer = 0):fixed(integer,0){}
|
real128( uint64_t integer = 0);
|
||||||
real128( const std::string& str );
|
explicit real128( const std::string& str );
|
||||||
operator std::string()const;
|
operator std::string()const;
|
||||||
|
|
||||||
friend real128 operator * ( real128 a, const real128& b ) { a *= b; return a; }
|
friend real128 operator * ( real128 a, const real128& b ) { a *= b; return a; }
|
||||||
|
|
@ -24,7 +24,7 @@ namespace fc {
|
||||||
real128& operator /= ( const real128& o );
|
real128& operator /= ( const real128& o );
|
||||||
real128& operator *= ( const real128& o );
|
real128& operator *= ( const real128& o );
|
||||||
|
|
||||||
uint64_t to_uint64()const{ return fixed.high_bits(); }
|
uint64_t to_uint64()const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint128 fixed;
|
uint128 fixed;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,19 @@
|
||||||
#include <fc/exception/exception.hpp>
|
#include <fc/exception/exception.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#define PRECISION (1000000ll * 1000000ll * 1000000ll)
|
||||||
|
|
||||||
namespace fc
|
namespace fc
|
||||||
{
|
{
|
||||||
|
uint64_t real128::to_uint64()const
|
||||||
|
{
|
||||||
|
return (fixed/PRECISION).to_uint64();
|
||||||
|
}
|
||||||
|
|
||||||
|
real128::real128( uint64_t integer )
|
||||||
|
{
|
||||||
|
fixed = uint128(integer) * PRECISION;
|
||||||
|
}
|
||||||
real128& real128::operator += ( const real128& o )
|
real128& real128::operator += ( const real128& o )
|
||||||
{
|
{
|
||||||
fixed += o.fixed;
|
fixed += o.fixed;
|
||||||
|
|
@ -22,7 +33,7 @@ namespace fc
|
||||||
|
|
||||||
fc::bigint self(fixed);
|
fc::bigint self(fixed);
|
||||||
fc::bigint other(o.fixed);
|
fc::bigint other(o.fixed);
|
||||||
self *= fc::bigint(uint128(0,-1));
|
self *= PRECISION;
|
||||||
self /= other;
|
self /= other;
|
||||||
fixed = self;
|
fixed = self;
|
||||||
|
|
||||||
|
|
@ -34,7 +45,7 @@ namespace fc
|
||||||
fc::bigint self(fixed);
|
fc::bigint self(fixed);
|
||||||
fc::bigint other(o.fixed);
|
fc::bigint other(o.fixed);
|
||||||
self *= other;
|
self *= other;
|
||||||
self /= fc::bigint(uint128(0,-1));
|
self /= PRECISION;
|
||||||
fixed = self;
|
fixed = self;
|
||||||
return *this;
|
return *this;
|
||||||
} FC_CAPTURE_AND_RETHROW( (*this)(o) ) }
|
} FC_CAPTURE_AND_RETHROW( (*this)(o) ) }
|
||||||
|
|
@ -55,7 +66,7 @@ namespace fc
|
||||||
++c;
|
++c;
|
||||||
digit = *c - '0';
|
digit = *c - '0';
|
||||||
}
|
}
|
||||||
fixed = fc::uint128(int_part, 0);
|
*this = real128(int_part);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -90,11 +101,10 @@ namespace fc
|
||||||
real128::operator std::string()const
|
real128::operator std::string()const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << to_uint64();
|
ss << std::string(fixed / PRECISION);
|
||||||
ss << '.';
|
ss << '.';
|
||||||
real128 frac(fixed.low_bits());
|
auto frac = (fixed % PRECISION) + PRECISION;
|
||||||
|
ss << std::string( frac ).substr(1);
|
||||||
ss << std::string( frac.fixed ).substr(1);
|
|
||||||
|
|
||||||
auto number = ss.str();
|
auto number = ss.str();
|
||||||
while( number.back() == '0' ) number.pop_back();
|
while( number.back() == '0' ) number.pop_back();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <fc/real128.hpp>
|
#include <fc/real128.hpp>
|
||||||
#define BOOST_TEST_MODULE Real128Test
|
#define BOOST_TEST_MODULE Real128Test
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <fc/log/logger.hpp>
|
||||||
|
|
||||||
using fc::real128;
|
using fc::real128;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
@ -16,7 +17,22 @@ BOOST_AUTO_TEST_CASE(real128_test)
|
||||||
BOOST_CHECK_EQUAL(string(real128(12345)), string("12345."));
|
BOOST_CHECK_EQUAL(string(real128(12345)), string("12345."));
|
||||||
BOOST_CHECK_EQUAL(string(real128(0)), string(real128("0")));
|
BOOST_CHECK_EQUAL(string(real128(0)), string(real128("0")));
|
||||||
|
|
||||||
|
real128 ten(10);
|
||||||
|
real128 two(2);
|
||||||
|
real128 twenty(20);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL( string(ten), "10." );
|
||||||
|
BOOST_CHECK_EQUAL( string(two), "2." );
|
||||||
|
BOOST_CHECK_EQUAL( string(ten+two), "12." );
|
||||||
|
BOOST_CHECK_EQUAL( string(ten-two), "8." );
|
||||||
|
BOOST_CHECK_EQUAL( string(ten*two), "20." );
|
||||||
|
BOOST_CHECK_EQUAL( string(ten/two), "5." );
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(real128("12345.6789").to_uint64(), 12345);
|
BOOST_CHECK_EQUAL(real128("12345.6789").to_uint64(), 12345);
|
||||||
BOOST_CHECK_EQUAL((real128("12345.6789")*10000).to_uint64(), 123456789);
|
BOOST_CHECK_EQUAL((real128("12345.6789")*10000).to_uint64(), 123456789);
|
||||||
BOOST_CHECK_EQUAL(string(real128("12345.6789")), string("12345.6789"));
|
BOOST_CHECK_EQUAL(string(real128("12345.6789")), string("12345.6789"));
|
||||||
|
|
||||||
|
wdump( (ten)(two)(twenty) );
|
||||||
|
wdump( (real128(uint64_t(-1)))(uint64_t(-1)) );
|
||||||
|
wdump((real128("12345.6789")) );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue