Thi*_* B. 6 c++ base-conversion bigint c++11 std-bitset
要生成UFI编号,我使用bitset大小为74.要执行UFI生成的第2步,我需要转换此数字:
9 444 732 987 799 592 368 290
(10000000000000000000000000000101000001000001010000011101011111100010100010)
Run Code Online (Sandbox Code Playgroud)
成:
DFSTTM62QN6DTV1
Run Code Online (Sandbox Code Playgroud)
通过将第一个表示转换为基数31并从表中获取等效的字符.
#define PAYLOAD_SIZE 74
// payload = binary of 9444732987799592368290
std::bitset<PAYLOAD_SIZE> bs_payload(payload);
/*
perform modulo 31 to obtain:
12(D), 14(F), 24(S), 25(T), 25, 19, 6, 2, 22, 20, 6, 12, 25, 27, 1
*/
Run Code Online (Sandbox Code Playgroud)
有没有办法在不使用外部BigInteger库的情况下对我的bitset执行转换?
编辑:BigInteger即使是干杯和赫斯,我终于完成了一堂课.- 阿尔夫的解决方案就像一个魅力
这段代码似乎有效。为了保证结果,我认为你需要做额外的测试。例如,首先使用小数字,您可以直接计算结果。
编辑:哦,现在我注意到您发布了所需的结果数字,并且它们匹配。意味着它总体上是好的,但仍未针对极端情况进行测试。
#include <assert.h>
#include <algorithm> // std::reverse
#include <bitset>
#include <vector>
#include <iostream>
using namespace std;
template< class Type > using ref_ = Type&;
namespace base31
{
void mul2( ref_<vector<int>> digits )
{
int carry = 0;
for( ref_<int> d : digits )
{
const int local_sum = 2*d + carry;
d = local_sum % 31;
carry = local_sum / 31;
}
if( carry != 0 )
{
digits.push_back( carry );
}
}
void add1( ref_<vector<int>> digits )
{
int carry = 1;
for( ref_<int> d : digits )
{
const int local_sum = d + carry;
d = local_sum % 31;
carry = local_sum / 31;
}
if( carry != 0 )
{
digits.push_back( carry );
}
}
void divmod2( ref_<vector<int>> digits, ref_<int> mod )
{
int carry = 0;
for( int i = int( digits.size() ) - 1; i >= 0; --i )
{
ref_<int> d = digits[i];
const int divisor = d + 31*carry;
carry = divisor % 2;
d = divisor/2;
}
mod = carry;
if( digits.size() > 0 and digits.back() == 0 )
{
digits.resize( digits.size() - 1 );
}
}
}
int main() {
bitset<74> bits(
"10000000000000000000000000000101000001000001010000011101011111100010100010"
);
vector<int> reversed_binary;
for( const char ch : bits.to_string() ) { reversed_binary.push_back( ch - '0' ); }
vector<int> base31;
for( const int bit : reversed_binary )
{
base31::mul2( base31 );
if( bit != 0 )
{
base31::add1( base31 );
}
}
{ // Check the conversion to base31 by converting back to base 2, roundtrip:
vector<int> temp31 = base31;
int mod;
vector<int> base2;
while( temp31.size() > 0 )
{
base31::divmod2( temp31, mod );
base2.push_back( mod );
}
reverse( base2.begin(), base2.end() );
cout << "Original : " << bits.to_string() << endl;
cout << "Reconstituted: ";
string s;
for( const int bit : base2 ) { s += bit + '0'; cout << bit; }; cout << endl;
assert( s == bits.to_string() );
}
cout << "Base 31 digits (msd to lsd order): ";
for( int i = int( base31.size() ) - 1; i >= 0; --i )
{
cout << base31[i] << ' ';
}
cout << endl;
cout << "Mod 31 = " << base31[0] << endl;
}
Run Code Online (Sandbox Code Playgroud)
MinGW g++ 的结果:
原件:10000000000000000000000000000101000001000001010000011101011111100010100010 重构:10000000000000000000000000000101000001000001010000011101011111100010100010 31 位基数(msd 到 lsd 顺序):12 14 24 25 25 19 6 2 22 20 6 12 25 27 1 模 31 = 1
| 归档时间: |
|
| 查看次数: |
578 次 |
| 最近记录: |