diff --git a/include/fc/crypto/sha256.hpp b/include/fc/crypto/sha256.hpp index a390c4f..a7e8deb 100644 --- a/include/fc/crypto/sha256.hpp +++ b/include/fc/crypto/sha256.hpp @@ -93,6 +93,7 @@ class sha256 uint32_t approx_log_32()const; void set_to_inverse_approx_log_32( uint32_t x ); + static double inverse_approx_log_32_double( uint32_t x ); uint64_t _hash[4]; }; diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 73b66fd..c1b8235 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -150,6 +151,16 @@ namespace fc { return; } + double sha256::inverse_approx_log_32_double( uint32_t x ) + { + uint8_t nzbits = uint8_t( x >> 0x18 ); + if( nzbits == 0 ) + return 0.0; + uint32_t b = 1 << 0x18; + uint32_t y = (x & (b-1)) | b; + return std::ldexp( y, int( nzbits ) - 0x18 ); + } + uint16_t sha256::clz()const { const uint8_t* my_bytes = (uint8_t*) data(); diff --git a/tests/crypto/log_test.cpp b/tests/crypto/log_test.cpp index fcd67de..654c95c 100644 --- a/tests/crypto/log_test.cpp +++ b/tests/crypto/log_test.cpp @@ -1,4 +1,6 @@ +#include + #include #include @@ -55,12 +57,23 @@ int main(int argc, char**argv, char** envp) std::cerr << "got error on log(" << str_h << ")" << std::endl; ++errors; } + double d_ilog_h_test = h.inverse_approx_log_32_double( ref_log ); h.set_to_inverse_approx_log_32( ref_log ); if( ref_log != h.approx_log_32() ) { std::cerr << "got error on ilog(" << ref_log << ")" << std::endl; ++errors; } + + std::string str_ilog_h = h.str(); + boost::multiprecision::uint256_t u256_ilog_h( "0x" + str_ilog_h ); + double d_ilog_h_ref = u256_ilog_h.template convert_to(); + if( d_ilog_h_ref != d_ilog_h_test ) + { + std::cerr << "got error on d_ilog(" << ref_log << ")" << std::endl; + ++errors; + } + if( h != fc::sha256() ) { fc::sha256 h_before = h;