2

所以我想从 int256_t 中取对数。

我发现了这一点,但将其修改为 sizeof int256_t 不起作用。它会给出不正确的结果: https ://stackoverflow.com/a/11376759

boost中是否有支持多精度的日志功能?

4

2 回答 2

0
template<class T, std::size_t...Is>
std::array<uint8_t, bytes> decomponse( std::index_sequence<Is...>, T in ) {
  return {{ (uint8_t)( in >> (8*( (sizeof...(Is)) - Is ) )) }};
}

template<std::size_t bytes, class T>
std::array<int8_t, bytes> decomponse( T in ) {
  return decompose( in, std::make_index_sequence<bytes>{} );
}

template<std::size_t bytes, class T>
double big_log2( T in ) {
  auto bytes_array = decompose<bytes>(in);
  std::size_t zeros = 0;
  for (auto byte:bytes_array) {
    if (byte) break;
    ++zeros;
  }
  int32_t tmp = 0;
  for (auto i = zeros; (i < bytes) && i < (zeros+4); ++i) {
    tmp |= bytes_array[i] << (8*(3 - (i-zeros)));
  }
  return log2(tmp) + (bytes-zeros-4)*8;
}

wherelog2(int32_t)生成一个 32 位值的 log2 并返回一个double.

根据字节序,反转bytes_array和修改算法可能会使其更快(理想情况下,它应该编译为 memcpy 或完全优化)。

这试图将 4 个最高有效字节推入 int32_t,取其对数,然后添加正确的数量以将其移动到所讨论的 N 字节整数的大小。

于 2017-11-03T19:12:45.803 回答
0

没有进一步的限制,我会写:

Live On Coliru

int256_t x("12345678901234567890");

std::cout << "log2(" << x << ") = " << log2(cpp_bin_float_100(x)) << "\n";

印刷

log2(12345678901234567890) = 63.4206

更简单

如果要对结果进行四舍五入,则不需要所有精度:

Live On Coliru

std::cout << "log2(" << x << ") = " << log2(x.convert_to<double>()) << "\n";

特别指定

一个非常粗略的形式可能如下所示:

Live On Coliru

template <typename T>
static inline int adhoc_log2(T i) {
    int n = 0;
    while(i /= 2) ++n;
    return n;
}

印刷

adhoc(12345678901234567890) = 63

最后,您确实可以退回到位级别并以@SamVarshavchik 建议的方式应用位摆弄技巧

于 2017-11-02T13:50:01.983 回答