我試圖做與靜態型別語言相同的數學運算,但如果引數很大,它會給我不同的數字。
function xorshiftmult(x) {
x ^= x >> 12n
x ^= x << 25n
x ^= x >> 27n
return BigInt.asUintN(64, x * 2685821657736338717n)
}
小數字:
input/output
1n 5180492295206395165n
2n 10360984590412790330n
3n 15541476885619185495n
4n 4961046764852367761n
5n 4769895744586085492n
6n 15322031355265158091n
7n 15130880334998875822n
8n 9922093529704735522n
9n 15102585824911130687n
大數字:
input/output
7292821753470094447n 4831377277631613306n
17517393223776413492n 8648459866934146562n
12871125787594255668n 10283147200615164616n
16549285201548370653n 6000770026373893856n
18260228909704403279n 13976674343699112182n
7574594482456054693n 16722430591553842838n
17620850200451425087n 15710702043522419077n
11252008783195621033n 12240320011096546170n
13791874522026752862n 7426906761295174006n
12869035004249813321n 1654853426672194495n
(golang)
func xorshiftmult(x uint64) uint64 {
x ^= x >> 12
x ^= x << 25
x ^= x >> 27
return x * 2685821657736338717
}
小數字:
input/output
1 5180492295206395165
2 10360984590412790330
3 15541476885619185495
4 4961046764852367761
5 4769895744586085492
6 15322031355265158091
7 15130880334998875822
8 9922093529704735522
9 15102585824911130687
大數字:
input/output
7292821753470094447 4375439080089995642
17517393223776413492 3385204219959375362
12871125787594255668 13047519269082376904
16549285201548370653 13622873389358370528
18260228909704403279 10325503129038119158
7574594482456054693 7461249648354733718
17620850200451425087 13330604890916407685
11252008783195621033 8666328877708335994
13791874522026752862 16881109032334662006
12869035004249813321 14233246107464520639
如您所見,大數字是不同的。但為什么?我做錯了什么?
uj5u.com熱心網友回復:
您需要在每一步都限制數字,而不僅僅是在最后。否則,當您再次向右移動時,您移到第 64 位之后向左移動的位稍后會回傳,而在圍棋中,它們已經“掉下懸崖”了。
例如,如果你的輸入是 2^50,第一步會給你 2^50 2^38,然后第二步是 2^50 2^38 2^75 2^63(而在 Go 中你會得到那時只有 2^50 2^38 2^63),所以在第三步之后你會得到 2^50 2^38 2^75 2^63 2^23 2^11 2^48 2^36(而在 Go 中 2^75 和 2^48 不存在)并且在鉗制后最終結果是 2^50 2^38 2^63 2^23 2^11 2^48 2^36 - 在 Go 中 2^48 不會存在,因為它來自第二步中的 2^75,在 Go 中它已經被夾住了,不能引入 2^ 48 下一步。
function xorshiftmult(x) {
x = BigInt.asUintN(64, x ^ x >> 12n)
x = BigInt.asUintN(64, x ^ x << 25n)
x = BigInt.asUintN(64, x ^ x >> 27n)
return x
}
注意:從技術上講,BigInt.asUintN只在<<步驟中使用就足夠了,因為>>步驟不能產生更大的數字,只能產生更小的數字。無論如何,為了一致性,我會這樣做,但如果考慮速度,則可以使用以下方法:
function xorshiftmult(x) {
x ^= x >> 12n
x = BigInt.asUintN(64, x ^ x << 25n)
x ^= x >> 27n
return x
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/343359.html
標籤:javascript 数学 位操作 大整数
