c++ - 使用 boost::multiprecision cpp_int 进行左移时超出时间限制错误
问题描述
我正在尝试以下操作:
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
cpp_int v = 1;
unsigned int a = 4294967295;
std::cout << (v << a) << std::endl;
return 0;
}
如何防止相同的错误?我们可以用 cpp_int 做的位移上限是多少。
解决方案
这分配了大量(浪费的)内存。
由于您可以使用十进制浮点数来表示此数字而不会损失任何精度,因此我会这样做:
注意1 << n
等于2^n
(pow(2, n)),所以你可以写:
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
namespace bmp = boost::multiprecision;
using number = bmp::number<bmp::cpp_dec_float<50, intmax_t> >;
int main() {
int64_t a = 0xffffffff;
std::cout << pow(number(2), a) << std::endl;
}
哪个是正确的
1.55164e+1292913986
您可以验证它是否正确:
for (intmax_t const a : { -8888ll, 0xFFFFll, 0xFFFFFFFFll, }) {
std::cout << pow(number(2), a) << std::endl;
auto roundtrip_exponent = bmp::log2(pow(number(2), a));
auto reverse = round(roundtrip_exponent).convert_to<intmax_t>();
std::cout << "Reverse: " << std::hex << std::showbase << reverse << std::dec << "\n";
std::cout << "Match: " << std::boolalpha << (a == reverse) << "\n";
}
在Coliru现场打印
2.78868e-2676
Reverse: 0xffffffffffffdd48
Match: true
1.00176e+19728
Reverse: 0xffff
Match: true
1.55164e+1292913986
Reverse: 0xffffffff
Match: true
在极端情况下,您将不可避免地在不精确的操作 (log2) 上失去一些精度。
如果您很好奇,您可能想尝试通过设置打印完整的精度std::fixed
:
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
namespace bmp = boost::multiprecision;
using number = bmp::number<bmp::cpp_dec_float<50, intmax_t> >;
int main() {
std::cout << std::fixed << pow(number(2), 0xFFFFFFFFll) << std::endl;
}
将输出重定向到文件!它将以十进制数字写入 1.3GiB。这应该可以解释为什么它不能很好地与任意精度整数表示一起工作。
所有输出压缩为:
0000000 3531 3135 3436 3230 3137 3339 3631 3334
0000020 3730 3130 3934 3439 3535 3737 3339 3831
0000040 3232 3937 3535 3631 3334 3936 3939 3038
0000060 3737 3938 3631 3338 3737 3030 3532 3339
0000100 3533 3538 3636 3230 3935 3039 3030 3030
0000120 3030 3030 3030 3030 3030 3030 3030 3030
*
11504046500 3030 2e30 3030 3030 3030 000a
11504046513
其中*
表示只有 0 位数字的行。然后你就会明白为什么我称之为浪费了
推荐阅读
- sql-server - 将 Azure SQL 连接到本地外部表错误:发生与网络相关或特定于实例的错误
- android - OpenGL:根据刷新率创建一个闪烁的黑/白屏幕(移动)
- javascript - 扁平化数组树js
- python - 在 Optuna 研究期间动态添加/删除参数时会发生什么?
- python - 访问使用 for 循环创建的条目小部件数据以进行绘图
- java - OSPermissionSubscriptionState:无法解析符号
- python - 当我尝试删除所有不以特定名称开头的行时,如何将列名保留在数据框中?
- python-3.x - 将操作应用于 numpy 数组中的特定列
- jackson - 字符串的杰克逊反序列化为 LocalDateTime 不一致
- javascript - 如何使用 t-jquery 和 t-operation 扩展模板属性(Odoo 14)