2 回答

TA貢獻2037條經驗 獲得超6個贊
Go 是否能夠計算非常大的數字,因為當數字開始變得非常大時需要更多內存時,語言能夠擴展堆棧大小?當這些數字開始變得如此之大以至于無法放入內存中的 32 或 64 位整數類型時,它們在哪里/如何存儲它們?
有點 - 它能夠做到這一點,因為當您使用 時math.Big,它本質上是將每個數字存儲為 的切片uint,以及一些額外的字段(例如數字的符號),其中切片中的每個項目代表單個數字數字。
如果 Go 能夠對不適合 int32 等基本類型的大量數字進行計算,為什么該語言會強制您將這些數字存儲在一個太小而無法處理的基本類型中?
該語言不會強迫您將它們存儲在該類型中 - 您可以自由使用math.Big所有數字。但一般來說,我們希望我們的代碼能夠快速運行,并且需要做的工作量是:
x := 21
y := 29
z := x + y
很少,而且會跑的很快。但這是一種折衷——你只需要意識到像這樣簡單的事情,當將每個數字存儲在一個切片中時,會變成更多的步驟。作為一個快速演示:(https://play.golang.org/p/rFWKbKy4FeQ):
x := []uint{2,1}
y := []uint{2,9}
result := []uint{}
xIndex := len(x) - 1
yIndex := len(y) - 1
carry := 0
for ; xIndex >= 0 || yIndex >= 0; {
z := uint(0)
if xIndex >= 0 && yIndex >= 0 {
z = x[xIndex] + y[yIndex]
} else if xIndex >= 0 {
z = x[xIndex]
} else {
z = y[yIndex]
}
if carry != 0 {
z++
}
if z >= 10 {
carry = 1
z = z % 10
}
xIndex--
yIndex--
result = append([]uint{z}, result...)
}
fmt.Println(result)
我仍然會得到正確的答案(在這種情況下,我什至還沒有擔心任何邊緣情況),但還有很多工作要做。如果每個數學運算都需要這么多的工作,那么 Go 就不會被認為是一種快速語言。

TA貢獻1826條經驗 獲得超6個贊
Go 是否能夠計算非常大的數字,因為當數字開始變得非常大時需要更多內存時,語言能夠擴展堆棧大???
不,堆棧和數學/大是完全無關的。
當這些數字開始變得如此之大以至于無法放入內存中的 32 或 64 位整數類型時,它們在哪里/如何存儲它們?
“哪里”:沒人知道。去吧,該語言不對事物的“存儲位置”做出任何聲明/保證。普通計算機有一個堆棧和一個堆,兩個最常見的 Go 編譯器決定將 math/big.Int 放在哪里。這個決定是針對每個變量單獨做出的。請注意,不同的編譯器版本可能會做出不同的決定。(谷歌“逃逸分析”了解詳情)。您可以假設 math/big.Int 存儲在堆中。
“如何”:閱讀 math/big.Int 的來源 :-) 基本上是幾個原始整數。請參閱https://golang.org/src/math/big/nat.go#L23(大致就像您以十進制編碼 > 9 的數字)。
如果 Go 能夠對不適合 int32 等基本類型的大量數字進行計算,為什么該語言會強制您將這些數字存儲在一個太小而無法處理的基本類型中?
這個問題假設“語言迫使您將這些數字存儲在一個太小而無法處理它們的基本類型中”,這是錯誤的。Go 中的“最大”整數類型是 uint64,如果這還不夠,您可以使用 math/big.Int 并且沒有人強迫您將 math/big.Int 存儲在其中一種原始類型中。
例如,如果 Go 能夠將兩個非常大的數字相加并確定一個看似沒有問題的結果,為什么我不能存儲這個值以供將來使用或不使用另一個庫將其打印到屏幕上呢?
假設“Go”是指原始內置類型:不,此 Go 無法對不適合使用的原始類型的數字進行計算。要對“大量數字”進行正確計算,您必須使用包 math/big。
請注意,一旦一個數字溢出 int(通常為 9223372036854775807),您的“斐波那契數的最后一位是完全錯誤的。Go over-/underflow 中的原始類型(在規范中查找確切的詳細信息)在這種情況下,結果定義明確但沒有比你期望的更長。
(旁注:Go 對常量的處理是不同的。)
- 2 回答
- 0 關注
- 157 瀏覽
添加回答
舉報