bash中固定宽度整数的宽度是多少?

时间:2014-09-30 13:06:10

标签: bash limit

Shell Arithmetic说:

  

以固定宽度整数进行评估,不检查溢出,   虽然除以0被捕获并标记为错误。

示例:

$ echo $(( 1 << 32 ))
4294967296
$ echo $(( (1 << 64) - 1 ))
0

bash中shell算法的整数限制是什么?

@rici pointed out POSIX shell保证签名长整数范围(由ISO C定义):

-2**31+1 to +2**31-1

@John Zwinck pointed out bash source code indicates that intmax_t is used

  

所有算术都以intmax_t整数完成,不检查溢出

bash是否保证在其文档中使用intmax_t或其他C类型作为整数?

2 个答案:

答案 0 :(得分:2)

Bash没有记录整数的精确大小,大小可能因平台而异。

但是,它确实尝试符合Posix,它指定算术扩展使用带符号的长算法,该算法必须至少为32位,包括符号位。

对于任何k的值,Posix不要求整数运算为2 k [但请参见注1],尽管常见平台上的bash会这样做,并且它特别不保证算术运算符的行为就像值是有符号长整数一样。 Posix甚至允许使用浮点模拟整数运算,只要浮点值具有足够的精度:

  

作为扩展,shell可以识别超出列出的算术表达式。 shell可以使用有符号整数类型,其等级大于有符号长度的等级。只要在没有溢出的情况下它不影响结果,shell可以使用实数浮点类型而不是有符号长。 (XSH§2.6.4)

这将允许在long仅为32位的平台上使用IEEE-754浮点双精度(53位精度)。虽然bash没有这样做 - 如文档所述,bash使用固定宽度的整数数据类型 - 其他shell实现可能,并且可移植代码不应该做出假设。


备注:

  1. Posix通常遵循ISO C标准,但有很多地方Posix添加了额外的约束,其中一些标记为扩展( CX ):

      

    POSIX.1-2008部分作为ISO C标准的概要,它可以选择进一步约束允许因ISO C标准而变化的行为。即使缺少CX标记,此类限制和其他兼容差异也不会被视为冲突。标记仅供参考。

    这些附加约束之一是精确宽度整数类型的存在。标准C需要类型int_{least,fast}{8,16,32,64}_t及其未签名的类似物。除非某些整数类型符合条件,否则它不需要精确宽度类型,例如int32_t。精确宽度类型必须具有其名称中指示的精确位数(即,没有填充位),并且必须具有2的补码表示。因此INT32_MIN,如果已定义,则必须正好为-2 31 (§7.20.2.1)。

    然而,Posix 需要精确宽度类型int{8,16,32}_t(以及无符号类似物),如果实现提供此类型,还需要int64_t 。特别是,如果“实现支持int64_t编程环境并且正在_POSIX_V7_LP64_OFF64编程环境中构建应用程序”,则需要_POSIX_V7_LP64_OFF64。 (XBD,§13,stdint.h)(这些要求标记为 CX 。)

    尽管int32_t必须存在,因此必须有一些2的补码类型,但仍然无法保证signed long是2的补码,即使它是,也有不保证整数溢出包裹,而不是例如陷阱。

    与原始问题最相关的是,即使signed longint64_t的类型相同,即使有符号整数溢出包裹,shell也没有任何义务实际上使用signed long进行算术扩展。它可以使用任何数据类型“只要它不会在没有溢出的情况下影响结果”。 (XSH,§2.6.4)

答案 1 :(得分:1)

Bash在其C算术实现中使用intmax_t。你可以在这里看到它:http://www.opensource.apple.com/source/bash/bash-30/bash/expr.c

这意味着它将成为最大的&#34;您平台上的整数类型。请记住,某些平台有更大的&#34;更大的&#34;整数,例如在某些64位平台上有128位整数,但那些非常特殊的&#34;这里不包括类型,所以大多数系统现在都会使用32或64位数学看到Bash。