要生成UFI number,请使用大小为bitset
的BigInteger
。要执行UFI生成的步骤2,我需要转换此数字:
9 444 732 987 799 592 368 290
(10000000000000000000000000000101000001000001010000011101011111100010100010)
进入:
DFSTTM62QN6DTV1
通过将第一个表示形式转换为基数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
*/
是否可以在不使用外部BigInteger库的情况下对我的位集执行转换?
答案 0 :(得分:3)
要获得数字的31模,只需要sum up the digits in base 32,就像计算小数的3和9模一样
unsigned mod31(std::bitset<74> b) {
unsigned mod = 0;
while (!b.none()) {
mod += (b & std::bitset<74>(0x1F)).to_ulong();
b >>= 5;
}
while (mod > 31)
mod = (mod >> 5) + (mod & 0x1F);
return mod;
}
您可以通过像how its done here一样并行运行加法来加快模数计算。类似的技术可用于计算模3、5、7、15 ...和2 31 -1
但是,由于问题实际上是关于基本转换的,而不是标题所称的模数,因此您需要为此进行实际划分。注意1 / b为0。(1)在基b +1中,我们有
然后可以这样计算x / 31
x / 31 = x * 2 -5 + x * 2 -10 + x * 2 -15 + ... < / p>
uint128_t result = 0;
while (x)
{
x >>= 5;
result += x;
}
由于模和除法均使用shift-by-5,因此您也可以在一个循环中将它们一起进行。
但是,这里最棘手的部分是如何正确舍入商。上面的方法适用于大多数值,除了31的倍数和2的下一个幂之间的某些值之外,我发现了一种方法,可以校正多达几千个值的结果,但尚未找到所有值的通用方法< / p>
您可以看到divide by 10和by 3使用了相同的移位加法。著名的Hacker's Delight中还有更多示例经过适当取整。我没有足够的时间阅读本书,以了解它们如何实现结果校正部分,因此也许以后再讲。如果有人有任何想法,将不胜感激。
一个建议是对定点进行除法。只需将值左移,以便我们有足够的小数部分可以在以后舍入
uint128_t result = 0;
const unsigned num_fraction = 125 - 75 // 125 and 75 are the nearest multiple of 5
// or maybe 128 - 74 will also work
uint128_t x = UFI_Number << num_fraction;
while (x)
{
x >>= 5;
result += x;
}
// shift the result back and add the fractional bit to round
result = (result >> num_fraction) + ((result >> (num_fraction - 1)) & 1)
请注意,您上面的结果不正确。我已经确认结果是来自Yaniv Shaked's answer和Wolfram alpha
的 CEOPPJ62MK6CPR1答案 1 :(得分:1)
此代码似乎有效。为了保证结果,我认为您需要进行其他测试。例如。首先使用小数字,您可以直接计算结果。
编辑:哦,现在我注意到您发布了所需的结果数字,并且它们匹配。意味着它总体上不错,但仍未针对极端情况进行测试。
//////////// NetworkService.js
const networkCall = (...args) => fetch(...) // say, returns promise
//////////// thunks/core/whatever.js
import { networkCall } from 'NetworkService'
const thunk = (...args) => (dispatch, getState) => {
dispatch(startFetch(...args))
const componentData = args
// I'd suggest using selectors here to pick only required data from store's state
// instead of passing WHOLE state to network layer, since it's a leaking abstraction
const storeData = getState()
networkCall(componentData, storeData)
.then(resp => dispatch(fetchOk(resp)))
.catch(err => dispatch(fetchFail(err)))
}
//////////// Component.js
import { thunk } from 'thunks/core/whatever'
const mapDispatchToProps = {
doSomeFetch: thunk,
}
const Component = ({ doSomeFetch }) =>
<button onClick={doSomeFetch}>Do some fetch</button>
// store.subscribe via `connect` from `react-redux`
const ConnectedComponent = connect(..., mapDispatchToProps)(Component)
MinGW g ++的结果:
Original : 10000000000000000000000000000101000001000001010000011101011111100010100010 Reconstituted: 10000000000000000000000000000101000001000001010000011101011111100010100010 Base 31 digits (msd to lsd order): 12 14 24 25 25 19 6 2 22 20 6 12 25 27 1 Mod 31 = 1
答案 2 :(得分:0)
我没有编译伪代码,但是您可以对如何转换数字有全面的了解:
// Array for conversion of value to base-31 characters:
char base31Characters[] =
{
'0',
'1',
'2',
...
'X',
'Y'
};
void printUFINumber(__int128_t number)
{
string result = "";
while (number != 0)
{
var mod = number % 31;
result = base31Characters[mod] + result;
number = number / 31;
}
cout << number;
}