十六进制转换构造函数根本不解析符号。同样,如果它们是负数,std::cout 将拒绝打印十六进制数,并且确实.str(..., std::ios::hex)
会抛出runtime_error
异常(“不支持以 8 或 16 为基数打印负数”)。
所以你必须让它手动工作,比如
UInt uval(str);
Int val;
if (/*signbit =*/uval >> 255) {
// manual two's complement
val = ~uval + 1;
val.backend().sign(true);
} else {
val = uval.convert_to<boost::multiprecision::int256_t>();
}
这是一个验证所有边缘情况的测试程序:
住在科利鲁
#include <boost/multiprecision/cpp_int.hpp>
#include <iomanip>
#include <iostream>
using namespace std::string_literals;
using UInt = boost::multiprecision::uint256_t;
using Int = boost::multiprecision::int256_t;
int main()
{
static const auto min = -Int(UInt(1) << 255);
static const auto max = Int(UInt(1) << 255 - 1);
static const auto dec = std::ios::dec;
static const auto hex = std::ios::hex | std::ios::showbase;
struct {
std::string_view caption;
Int expected;
std::string str;
} testcases[] = {
// clang-format off
{"zero", 0, Int{0}.str(0, dec),},
{"zero", 0, Int{0}.str(0, hex),},
//
{"one", 1, Int{1}.str(0, dec),},
{"one", 1, Int{1}.str(0, hex),},
//
{"negone", -1, Int{-1}.str(0, dec),},
{"negone", -1, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"s,},
//
{"min", min, (min).str(0, dec),},
{"min", min, "0x8000000000000000000000000000000000000000000000000000000000000000"s,},
//
{"min+1", min+1, (min + 1).str(0, dec),},
{"min+1", min+1, "0x8000000000000000000000000000000000000000000000000000000000000001"s,},
//
{"max-1", max-1, (max - 1).str(0, dec),},
{"max-1", max-1, (max - 1).str(0, hex),},
//
{"max", max, (max).str(0, dec),},
{"max", max, (max).str(0, hex),},
// question case
{"question", -1234, "-1234"s,},
{"question", -1234, "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb2e"s,},
// clang-format on
};
for (auto [caption, expected, str] : testcases) {
std::cout << " ---- " << caption << ":\t\t" << str << "\n";
UInt uval(str);
Int val;
if (/*signbit =*/uval >> 255) {
// manual two's complement
val = ~uval + 1;
val.backend().sign(true);
} else {
val = uval.convert_to<boost::multiprecision::int256_t>();
}
std::cout << "Expected? " << std::boolalpha
<< (expected == val ? "SUCCESS" : "FAILED") << "\t";
std::cout << std::dec << val;
if (val.sign() >= 0) // negative no hex
std::cout << " (" << std::hex << std::showbase << val << ")";
std::cout << "\n";
}
}
印刷
---- zero: 0
Expected? SUCCESS 0 (0x0)
---- zero: 0x0
Expected? SUCCESS 0 (0x0)
---- one: 1
Expected? SUCCESS 1 (0x1)
---- one: 0x1
Expected? SUCCESS 1 (0x1)
---- negone: -1
Expected? SUCCESS -1
---- negone: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Expected? SUCCESS -1
---- min: -57896044618658097711785492504343953926634992332820282019728792003956564819968
Expected? SUCCESS -57896044618658097711785492504343953926634992332820282019728792003956564819968
---- min: 0x8000000000000000000000000000000000000000000000000000000000000000
Expected? SUCCESS -57896044618658097711785492504343953926634992332820282019728792003956564819968
---- min+1: -57896044618658097711785492504343953926634992332820282019728792003956564819967
Expected? SUCCESS -57896044618658097711785492504343953926634992332820282019728792003956564819967
---- min+1: 0x8000000000000000000000000000000000000000000000000000000000000001
Expected? SUCCESS -57896044618658097711785492504343953926634992332820282019728792003956564819967
---- max-1: 28948022309329048855892746252171976963317496166410141009864396001978282409983
Expected? SUCCESS 28948022309329048855892746252171976963317496166410141009864396001978282409983 (0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
---- max-1: 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Expected? SUCCESS 28948022309329048855892746252171976963317496166410141009864396001978282409983 (0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
---- max: 28948022309329048855892746252171976963317496166410141009864396001978282409984
Expected? SUCCESS 28948022309329048855892746252171976963317496166410141009864396001978282409984 (0x4000000000000000000000000000000000000000000000000000000000000000)
---- max: 0x4000000000000000000000000000000000000000000000000000000000000000
Expected? SUCCESS 28948022309329048855892746252171976963317496166410141009864396001978282409984 (0x4000000000000000000000000000000000000000000000000000000000000000)
---- question: -1234
Expected? SUCCESS -1234
---- question: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb2e
Expected? SUCCESS -1234
附言
作为旁注,显然数字限制是不可信的,所以我在上面回避了它们。
assert(std::numeric_limits<UInt>::max() != std::numeric_limits<Int>::max());
assert(std::numeric_limits<UInt>::min() != std::numeric_limits<Int>::min());