Bash沒有記錄整數的確切大小,並且大小可能因平臺而異。
但是,它確實試圖符合Posix,它指定算術擴展使用帶符號的長算術,它必須至少包含32位(包括符號位)。
的Posix不需要整數運算是模2 ķ爲k
任何值,但見注1],雖然bash
共同平臺將這樣做,而且特別不保證算術運算符的行爲完全就好像這些值是經過長時間簽名的。 Posix甚至允許使用浮點模擬整數運算,前提是浮點值具有足夠的精度:
作爲擴展,shell可以識別超出列出的算術表達式。 shell可能使用一個有符號整數類型,其排名大於signed long的排名。在沒有溢出的情況下,只要不影響結果,shell可以使用真實浮點型而不是長整型。 (XSH § 2.6.4)
這將允許一個平臺,long
僅爲32位,例如在使用IEEE-754浮點數的加倍(精度53位)。雖然bash
不這樣做 - 正如文檔中所述,bash
使用固定寬度的整數數據類型 - 其他shell實現可能會和可移植代碼不應做出假設。
注:
的Posix通常推遲到ISO C標準,但也有一些地方的Posix增加了一個附加的約束,其中的一些被標記爲擴展(CX):
POSIX.1-2008部分地作爲ISO C標準的一部分,它可以選擇進一步構建ain行爲允許根據ISO C標準而變化。即使缺少CX標記,這些限制和其他兼容差異也不會被視爲衝突。標記僅供參考。
其中一個附加約束是存在精確寬度的整數類型。標準C要求類型int_{least,fast}{8,16,32,64}_t
及其無符號類似物。它不需要精確寬度類型,例如int32_t
,除非某些整數類型符合要求。精確寬度類型必須正好具有其名稱中指示的位數(即沒有填充位),並且必須具有2的補碼錶示。因此INT32_MIN
,如果已定義,則必須正好-2 (§ 7.20.2.1)。
然而,Posix的確實需要的確切寬類型int{8,16,32}_t
(以及無符號類似物),並且也int64_t
如果這樣的類型是由實現提供。特別是,如果「實現支持_POSIX_V7_LP64_OFF64
編程環境並且應用程序正在編程環境中構建,則需要int64_t
」。 (XBD,§ 13,stdint.h
)(這些要求都被標記爲CX。)
儘管int32_t
必須存在,因此必須有一些2的補碼型可用的事實,但仍然沒有保證signed long
是2的補碼,即使是這樣,也不能保證整數溢出迴繞,而不是例如陷阱。
最爲相關的原題,雖然是事實,即使signed long
是同一類型int64_t
即使有符號整數溢出環繞,外殼是沒有根據實際使用signed long
的算術擴展的任何義務。它可以使用任何數據類型「只要在沒有溢出的情況下不影響結果」。 (XSH,§ 2.6.4)
我不認爲在飛越(!)後減1(!)將有助於:-)嘗試echo $(((1 << 63) - 1)).. 9223372036854775807 – 2014-09-30 13:09:11
@MarkSetchell:關鍵是我的機器上有'1 << 64'溢出。在這種情況下結果並不重要。 – jfs 2014-09-30 13:10:14
我曾幻想你在做一個二進制搜索以找到沒有溢出的移位... << 48,<< 56,<< 60, – 2014-09-30 13:12:18