What is the width of fixed width integers in bash?

Shell arithmetic says:

Evaluation is performed on fixed-width integers without overflow checking, although division by 0 is trapped and flagged as an error.

Example:

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

      

What are integer limits in shell arithmetic in bash?

@rici pointed out that the POSIX wrapper guarantees a signed long integer range (as defined by ISO C):

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

      

@John Zvink pointed out that the Source code indicates that b : bash

intmax_t

All arithmetic is performed as intmax_t

integers without overflow checking

Does bash provide in its documentation what it uses intmax_t

or some other type of C for integers?

+3


source to share


2 answers


Bash does not document the exact size of integers, and the size can vary from platform to platform.

However, it tries to do Posix, which indicates that the arithmetic expansion uses signed long arithmetic, which must be at least 32 bits, including the sign bit.

Posix does not require modulo 2k integer arithmetic for any value k

[but see note 1], although bash

on common platforms it will, and it does not particularly guarantee that arithmetic operators will behave exactly the same as if the values ​​were signed for a long time ... Posix even allows you to simulate integer floating point arithmetic, provided the floating point values ​​are of sufficient precision:

As an extension, the shell can recognize arithmetic expressions outside of those listed. The wrapper can use a signed integer type with a rank greater than the rank of a signed long. The shell can use a real float instead of a signed one for a long time, as long as it does not affect the results in cases where no overflow occurs. (XSH, section 2.6.4)



This would allow IEEE-754 floating point doubling (53 bits of precision) to be used on a platform where it long

was, for example, 32 bits. While it bash

does not - as described in the doc bash

uses a fixed-width integer data type - other wrapper implementations are possible, and portable code need not make assumptions.


Notes:

  • Posix usually departs from the ISO C standard, but there are a number of places where Posix adds an additional restriction, some of which are marked as extensions ( CX):

    POSIX.1-2008 acts in part as a profile of the ISO C standard, and it can choose to further restrict the behavior, which may vary according to the ISO C standard. Such restrictions and other compatible differences are not considered conflicts even if there is no CX label. The marking is for information only.

    One of these additional restrictions is the existence of exact-width integers. The C standard requires types int_{least,fast}{8,16,32,64}_t

    and their unsigned counterparts. It does not require exact width types such as int32_t

    if no integer type is used. An exact-width type must have exactly the number of bits specified in its name (i.e., No padding bits) and must have a 2's-complement representation. So, INT32_MIN

    if it is defined it should be -2 31 (& section 7.20.2.1).

    However, Posix requires exact width types int{8,16,32}_t

    (as well as unsigned counterparts), and also int64_t

    if the type is supported by the implementation. In particular, int64_t

    it is required if "the implementation supports the programming environment _POSIX_V7_LP64_OFF64

    and the application is built in the programming environment. _POSIX_V7_LP64_OFF64

    " (XBD, Β§ 13, stdint.h

    ) (These requirements are marked as CX.)

    Even though there int32_t

    should exist and therefore should be available 2 types of complement, there is still no guarantee that it signed long

    is 2'-complement, and even if it does, there is no guarantee that the overflow integer wraps around rather than, for example, capture.

    Most relevant to the original question, however, is the fact that even if signed long

    is the same type as int64_t

    and even if the solid integer overflow is rounded off, the shell does not have to actually use it signed long

    for arithmetic expansion. It can use any data type "as long as it does not affect results in cases where there is no overflow." (XSH, section 2.6.4)

+2


source


Bash uses intmax_t

C arithmetic in its implementation. You can see it here: http://www.opensource.apple.com/source/bash/bash-30/bash/expr.c



This means it will be the "largest" integer type on your platform. Be aware that some platforms have "even larger" integers, for example. 128 bits on some 64-bit platforms, but these "extraordinary" types are not included here, so most systems will see Bash using 32 or 64-bit math.

+1


source







All Articles