mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 08:46:49 +08:00
Let us adjust the powers instead.
This commit is contained in:
parent
1afba556e3
commit
d521ddf7f7
@ -60,36 +60,6 @@ namespace {
|
||||
fastfloat_really_inline int power(int q) noexcept {
|
||||
return (((152170 + 65536) * q) >> 16) + 63;
|
||||
}
|
||||
// Checks whether w is divisible by 5**-q. If it returns true, then
|
||||
// w is definitively divisible by 5**-q.
|
||||
inline bool is_divisible(int64_t q, uint64_t w) noexcept {
|
||||
if((q>=-18) || (q<-27)) { return false; }
|
||||
int64_t pos_q = -q;
|
||||
// For each pair, first entry is the multiplicative inverse of 5**-q
|
||||
// and the second one is the largest quotient.
|
||||
//
|
||||
// This could be more efficient by using...
|
||||
// Faster remainder by direct computation: Applications to compilers and software libraries
|
||||
// Software: Practice and Experience 49 (6), 2019.
|
||||
// but the following is simple enough.
|
||||
constexpr static uint64_t table[10][2] = {
|
||||
{0xc1773b91fac10669,0x49c977}, // inverse of 5**18
|
||||
{0x26b172506559ce15,0xec1e4}, // inverse of 5**19
|
||||
{0xd489e3a9addec2d1,0x2f394}, // inverse of 5**20
|
||||
{0x90e860bb892c8d5d,0x971d}, // inverse of 5**21
|
||||
{0x502e79bf1b6f4f79,0x1e39}, // inverse of 5**22
|
||||
{0xdcd618596be30fe5,0x60b}, // inverse of 5**23
|
||||
{0x2c2ad1ab7bfa3661,0x135}, // inverse of 5**24
|
||||
{0x8d55d224bfed7ad,0x3d}, // inverse of 5**25
|
||||
{0x1c445d3a8cc9189,0xc}, // inverse of 5**26
|
||||
{0xcd27412a54f5b6b5,0x2}, // inverse of 5**27
|
||||
};
|
||||
uint64_t inverse = table[pos_q-18][0];
|
||||
uint64_t threshold = table[pos_q-18][1];
|
||||
uint64_t product = w * inverse;
|
||||
if(product > threshold) { return false; }
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@ -131,13 +101,8 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
||||
// In some very rare cases, this could happen, in which case we might need a more accurate
|
||||
// computation that what we can provide cheaply. This is very, very unlikely.
|
||||
//
|
||||
// There is still a chance to recover. If w is divisible by 5**-q,
|
||||
if(!is_divisible(q,w)) {
|
||||
answer.power2 = -1; // This (a negative value) indicates an error condition.
|
||||
return answer;
|
||||
}
|
||||
product.low += 1;
|
||||
product.high += 1;
|
||||
answer.power2 = -1; // This (a negative value) indicates an error condition.
|
||||
return answer;
|
||||
}
|
||||
// The "compute_product_approximation" function can be slightly slower than a branchless approach:
|
||||
// value128 product = compute_product(q, w);
|
||||
|
||||
@ -347,16 +347,16 @@ const uint64_t power_of_five_128[]= {
|
||||
0xa2425ff75e14fc31,0xa1258379a94d028d,
|
||||
0xcad2f7f5359a3b3e,0x96ee45813a04330,
|
||||
0xfd87b5f28300ca0d,0x8bca9d6e188853fc,
|
||||
0x9e74d1b791e07e48,0x775ea264cf55347d,
|
||||
0xc612062576589dda,0x95364afe032a819d,
|
||||
0xf79687aed3eec551,0x3a83ddbd83f52204,
|
||||
0x9abe14cd44753b52,0xc4926a9672793542,
|
||||
0xc16d9a0095928a27,0x75b7053c0f178293,
|
||||
0xf1c90080baf72cb1,0x5324c68b12dd6338,
|
||||
0x971da05074da7bee,0xd3f6fc16ebca5e03,
|
||||
0xbce5086492111aea,0x88f4bb1ca6bcf584,
|
||||
0xec1e4a7db69561a5,0x2b31e9e3d06c32e5,
|
||||
0x9392ee8e921d5d07,0x3aff322e62439fcf,
|
||||
0x9e74d1b791e07e48,0x775ea264cf55347e,
|
||||
0xc612062576589dda,0x95364afe032a819e,
|
||||
0xf79687aed3eec551,0x3a83ddbd83f52205,
|
||||
0x9abe14cd44753b52,0xc4926a9672793543,
|
||||
0xc16d9a0095928a27,0x75b7053c0f178294,
|
||||
0xf1c90080baf72cb1,0x5324c68b12dd6339,
|
||||
0x971da05074da7bee,0xd3f6fc16ebca5e04,
|
||||
0xbce5086492111aea,0x88f4bb1ca6bcf585,
|
||||
0xec1e4a7db69561a5,0x2b31e9e3d06c32e6,
|
||||
0x9392ee8e921d5d07,0x3aff322e62439fd0,
|
||||
0xb877aa3236a4b449,0x9befeb9fad487c3,
|
||||
0xe69594bec44de15b,0x4c2ebe687989a9b4,
|
||||
0x901d7cf73ab0acd9,0xf9d37014bf60a11,
|
||||
|
||||
@ -8,7 +8,7 @@ for q in range(-342,0):
|
||||
z = 0
|
||||
while( (1<<z) < power5) :
|
||||
z += 1
|
||||
if(q >= -17):
|
||||
if(q >= -27):
|
||||
b = z + 127
|
||||
c = 2 ** b // power5 + 1
|
||||
format(c)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user