第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

浮點數(shù)的字節(jié)順序

浮點數(shù)的字節(jié)順序

Go
喵喔喔 2023-06-05 17:26:37
我正在研究由 BadgerDB ( https://github.com/dgraph-io/badger ) 支持的 Tormenta?(?https://github.com/jpincas/tormenta?)。BadgerDB 按字節(jié)順序存儲鍵(字節(jié)片段)。我正在創(chuàng)建包含需要按順序存儲的浮點數(shù)的鍵,以便我可以正確地使用 Badger 的鍵迭代。我沒有扎實的 CS 背景,所以我有點力不從心。我這樣編碼浮點數(shù)binary.Write(buf, binary.BigEndian, myFloat):這對正浮點數(shù)很有效&mdash;&mdash;關(guān)鍵順序是你所期望的,但字節(jié)順序?qū)ω?fù)浮點數(shù)不適用。順便說一句,int 存在同樣的問題,但我能夠通過翻轉(zhuǎn) int 上的符號位b[0] ^= 1 << 7(保存對bint[]byte進(jìn)行編碼的結(jié)果)然后在檢索密鑰時翻轉(zhuǎn)回去來相對容易地解決這個問題。盡管b[0] ^= 1 << 7DOES 也會翻轉(zhuǎn)浮點數(shù)上的符號位,從而將所有負(fù)浮點數(shù)放在正數(shù)浮點數(shù)之前,但負(fù)數(shù)浮點數(shù)的順序是錯誤的(向后)。需要翻轉(zhuǎn)符號位并反轉(zhuǎn)負(fù)浮點數(shù)的順序。XOR 所有正數(shù)與 0x8000... 和負(fù)數(shù)與 0xffff...。這應(yīng)該翻轉(zhuǎn)兩者的符號位(因此負(fù)數(shù)首先出現(xiàn)),然后反轉(zhuǎn)負(fù)數(shù)的順序。然而,這遠(yuǎn)遠(yuǎn)超出了我的 bit-flipping-skills 水平,所以我希望 Go bit-ninja 可以幫助我將其轉(zhuǎn)化為一些 Go 代碼。
查看完整描述

1 回答

?
慕絲7291255

TA貢獻(xiàn)1859條經(jīng)驗 獲得超6個贊

使用math.Float64bits()

您可以使用math.Float64bits()which 返回一個與傳遞給它的uint64值具有相同字節(jié)/位的值float64

一旦有了uint64,對其執(zhí)行按位運算就很簡單了:

f := 1.0 // Some float64 value


bits := math.Float64bits(f)

if f >= 0 {

? ? bits ^= 0x8000000000000000

} else {

? ? bits ^= 0xffffffffffffffff

}

然后序列化該bits值而不是ffloat64 值,就大功告成了。


讓我們看看實際效果。float64讓我們創(chuàng)建一個包含數(shù)字及其字節(jié)的包裝器類型:


type num struct {

? ? f? ? float64

? ? data [8]byte

}

讓我們創(chuàng)建這些 s 的一部分num:


nums := []*num{

? ? {f: 1.0},

? ? {f: 2.0},

? ? {f: 0.0},

? ? {f: -1.0},

? ? {f: -2.0},

? ? {f: math.Pi},

}

序列化它們:


for _, n := range nums {

? ? bits := math.Float64bits(n.f)

? ? if n.f >= 0 {

? ? ? ? bits ^= 0x8000000000000000

? ? } else {

? ? ? ? bits ^= 0xffffffffffffffff

? ? }

? ? if err := binary.Write(bytes.NewBuffer(n.data[:0]), binary.BigEndian, bits); err != nil {

? ? ? ? panic(err)

? ? }

}

這就是我們?nèi)绾伟醋止?jié)對它們進(jìn)行排序:


sort.Slice(nums, func(i int, j int) bool {

? ? ni, nj := nums[i], nums[j]

? ? for k := range ni.data {

? ? ? ? if bi, bj := ni.data[k], nj.data[k]; bi < bj {

? ? ? ? ? ? return true // We're certain it's less

? ? ? ? } else if bi > bj {

? ? ? ? ? ? return false // We're certain it's not less

? ? ? ? } // We have to check the next byte

? ? }

? ? return false // If we got this far, they are equal (=> not less)

})

現(xiàn)在讓我們看看按字節(jié)排序后的順序:


fmt.Println("Final order byte-wise:")

for _, n := range nums {

? ? fmt.Printf("% .7f %3v\n", n.f, n.data)

}

輸出將是(在Go Playground上嘗試):


Final order byte-wise:

-2.0000000 [ 63 255 255 255 255 255 255 255]

-1.0000000 [ 64? 15 255 255 255 255 255 255]

?0.0000000 [128? ?0? ?0? ?0? ?0? ?0? ?0? ?0]

?1.0000000 [191 240? ?0? ?0? ?0? ?0? ?0? ?0]

?2.0000000 [192? ?0? ?0? ?0? ?0? ?0? ?0? ?0]

?3.1415927 [192? ?9? 33 251? 84? 68? 45? 24]

沒有math.Float64bits()

另一種選擇是先序列化float64值,然后對字節(jié)執(zhí)行異或運算。


如果數(shù)字是正數(shù)(或零),則第一個字節(jié)與 異或0x80,其余字節(jié)與 異或0x00,這基本上對它們什么都不做。


如果數(shù)字是負(fù)數(shù),則將所有字節(jié)與 異或0xff,這基本上是按位求反。


實際上:唯一不同的部分是序列化和 XOR 操作:


for _, n := range nums {

? ? if err := binary.Write(bytes.NewBuffer(n.data[:0]), binary.BigEndian, n.f); err != nil {

? ? ? ? panic(err)

? ? }

? ? if n.f >= 0 {

? ? ? ? n.data[0] ^= 0x80

? ? } else {

? ? ? ? for i, b := range n.data {

? ? ? ? ? ? n.data[i] = ^b

? ? ? ? }

? ? }

}

其余的是一樣的。輸出也將相同。



查看完整回答
反對 回復(fù) 2023-06-05
  • 1 回答
  • 0 關(guān)注
  • 270 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號