將 big.Int 轉換為 int64,反之亦然以及二進位補碼
php小編柚子將為您介紹如何在PHP中將big.Int轉換為int64,以及如何將int64轉換為big.Int。在電腦程式設計中,big.Int和int64是兩種不同的資料類型,big.Int用於處理大型整數,而int64是一種64位元的有符號整數類型。在進行型別轉換時,我們需要注意二進制補碼的概念,它是計算機中表示有符號整數的一種方式。接下來,我們將詳細介紹這兩種類型之間的轉換過程。
問題內容
我正在嘗試將表示 128 位元整數的 go big.int 轉換為 [2]int64。這個想法是為了能夠匹配 rust 的 i128::to_le_bytes(),它將 128 位元有符號整數編碼為小端位元組順序。此範例與 rust 的 i128::to_le_bytes()
相符。每當我嘗試將其轉換回 big.int 時,我都不會得到相同的值。進行初始右移時是否遺失了任何位元?謝謝。
package main import ( "encoding/binary" "fmt" "math/big" ) func main() { initial := new(big.Int) initial.SetString("-42", 10) value, _ := new(big.Int).SetString("-42", 10) var result [2]int64 result[0] = value.Int64() result[1] = value.Rsh(value, 64).Int64() leRepresentation := make([]byte, 16) binary.LittleEndian.PutUint64(leRepresentation[:8], uint64(result[0])) binary.LittleEndian.PutUint64(leRepresentation[8:], uint64(result[1])) fmt.Println(leRepresentation) fmt.Println(result) reverse := big.NewInt(result[1]) reverse.Lsh(reverse, 64) reverse.Add(reverse, big.NewInt(result[0])) fmt.Println(reverse.String()) fmt.Println(initial.String() == reverse.String()) }
解決方法
這裡有很多問題:
value
無法以 int64
表示,因此 value.int64()
的結果未定義。
您的較低位元沒有考慮 int64
的簽章結果,因此您可能會在結果中加上負數。您需要使用 uint64
(或至少在將其新增至 big.int
之前對其進行轉換)。
您正在 rsh
方法中改變 value
,因此即使正確重新建立了該值,最後的比較也會失敗。如果要比較的話,新建一個 big.int
來儲存原始值。
如果您想要 big.int
的原始資料表示形式恰好為 128 位,您可以使用 fillbytes
方法。我們可以採用大端資料並建立 2 個 64 位元值,如下所示:
b := make([]byte, 16) value.fillbytes(b) var result [2]uint64 result[0] = binary.bigendian.uint64(b[:8]) result[1] = binary.bigendian.uint64(b[8:])
既然位元組順序已經固定,請將符號位元加入結果。然而,為了使其像 int128
一樣運作,我們需要使用二進位補碼來設定符號
const sign = uint64(1 << 63) if value.sign() < 0 { // convert the unsigned value to two's compliment result[0] = ^result[0] result[1] = ^result[1] result[1]++ // check for carry if result[1] == 0 { result[0]++ } }
要建立一個新的 big.int
,請顛倒整個過程:
neg := uint128[0]&sign != 0 if neg { // reverse the two's compliment if uint128[1] == 0 { uint128[0]-- } uint128[1]-- uint128[0] = ^uint128[0] uint128[1] = ^uint128[1] } b := make([]byte, 16) binary.BigEndian.PutUint64(b[:8], uint128[0]) binary.BigEndian.PutUint64(b[8:], uint128[1]) result := new(big.Int).SetBytes(b) if neg { result.Neg(result) }
測試多個鍵值的範例:https://go.dev/play/ p/e1e-5cilflr
由於輸出被寫入為無符號值,因此如果可以以值 > maxint128 開頭,您還應該添加一個檢查以確保不會溢出符號值。將它們儲存為[2]int64
會更加混亂,因為我們需要uint64 值進行位元運算,並且我們需要確保int64
值不會透過它們自己的補碼進行滾動。在這種情況下,圍繞給定函數將 [2]int64
與 [2]uint64
相互轉換會更容易。
以上是將 big.Int 轉換為 int64,反之亦然以及二進位補碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

goisidealforbeginnersandsubableforforcloudnetworkservicesduetoitssimplicity,效率和concurrencyFeatures.1)installgromtheofficialwebsitealwebsiteandverifywith'.2)

Golang適合快速開發和並發場景,C 適用於需要極致性能和低級控制的場景。 1)Golang通過垃圾回收和並發機制提升性能,適合高並發Web服務開發。 2)C 通過手動內存管理和編譯器優化達到極致性能,適用於嵌入式系統開發。

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。Golang以其并发模型和高效性能著称,Python则以简洁语法和丰富库生态系统著称。

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。

C 更適合需要直接控制硬件資源和高性能優化的場景,而Golang更適合需要快速開發和高並發處理的場景。 1.C 的優勢在於其接近硬件的特性和高度的優化能力,適合遊戲開發等高性能需求。 2.Golang的優勢在於其簡潔的語法和天然的並發支持,適合高並發服務開發。
