亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

將 json 解組為浮動。為什么需要 float64?

將 json 解組為浮動。為什么需要 float64?

Go
翻閱古今 2023-07-31 15:58:50
我注意到 go unmarshals json floats 的方式有一些奇怪的行為。有些數字(但不是全部)拒絕正確解組。解決這個問題就像在目標變量中使用 float64 而不是 float32 一樣簡單,但我一生都找不到出現這種情況的充分理由。這是演示該問題的代碼:package mainimport (    "encoding/json"    "fmt"    . "github.com/shopspring/decimal")func main() {    bytes, _ := json.Marshal(369.1368) // not every number is broken, but this one is    fmt.Println("bytes", string(bytes))    var f32 float32    json.Unmarshal(bytes, &f32)    fmt.Printf("f32 %f\n", f32) // adds an extra 0.00001 to the number    var d Decimal    json.Unmarshal(bytes, &d)    fmt.Printf("d %s\n", d) // 3rd party packages work    // naw, you can just float64    var f64 float64    json.Unmarshal(bytes, &f64)    fmt.Printf("f64 %f\n", f64) // float64 works}不需要 float64 來準確表示我的示例數字,那么為什么這里需要呢?去游樂場鏈接:https://play.golang.org/p/tHkonQtZoCt
查看完整描述

1 回答

?
30秒到達戰場

TA貢獻1828條經驗 獲得超6個贊

您的斷言是錯誤的:不能369.1368精確表示。?float32?float64

最接近的float32值是(大約)369.136810302734375,它四舍五入到369.13681您的額外數字的來源。最接近的float64值是(大約)369.13679999999999382,它更適合您的目的。

(當然,如果您將其中任何一個四舍五入到小數點后四位數字,您就會得到您期望的數字。)

表示Decimal是精確的:沒有舍入誤差。

JSON 傳輸和接收以十進制表示的浮點值,但實際實現以各種語言表示,然后以不同的方式對這些數字進行編碼。根據您通過 JSON 通信的實體類型,通過編碼和解碼Decimal可以完全按照您的意愿保留數字,但請注意,用 C++ 或 Python 編寫的程序可能會將您的數字解碼為不同的浮點數-點精度并引入各種舍入誤差。

此 Go Playground 示例使用新添加的%x格式,并向您展示數字如何在內部存儲:

作為 float32 = 369.13681030273437500 (float32),這實際上是 12095875p-15 或 0x1.712306p+08

和:

作為 float64 = 369.136799999999999382 (float64),實際上是 6493923261440380p-44 或 0x1.712305532617cp+08

也就是說,數字 369。無論內部以二進制表示。它在 2?8?= 256 和 2?9?= 512 之間。在二進制中,它是 1 256、無 128、1 64、1 32、1 16、無 8、無 4、無 2 和 1 1:1.01110001 某物x?2?8。格式%b以一種方式表達%x,另一種格式以(1 . 0111 0010)%x開頭。1.72

查看完整回答
反對 回復 2023-07-31
  • 1 回答
  • 0 關注
  • 131 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號