Unsigned integers (The GNU Fortran Compiler)

#### 5.1.34 Unsigned integers ¶

If the `-funsigned` option is given, GNU Fortran supports unsigned integers according to J3/24-116. The data type is called `UNSIGNED`. For an unsigned type with `n` bits, it implements integer arithmetic modulo `2**n`, comparable to the `unsigned` data type in C.

The data type has `KIND` numbers comparable to other Fortran data types, which can be selected via the `SELECTED_UNSIGNED_KIND` function.

Mixed arithmetic, comparisons and assignment between `UNSIGNED` and other types are only possible via explicit conversion. Conversion from `UNSIGNED` to other types is done via type conversion functions like `INT` or `REAL`. Conversion from other types to `UNSIGNED` is done via `UINT`. Unsigned variables cannot be used as index variables in `DO` loops or as array indices.

Unsigned numbers have a trailing `u` as suffix, optionally followed by a `KIND` number separated by an underscore.

Input and output can be done using the ‘`I`’, ‘`B`’, ‘`O`’ and ‘`Z`’ descriptors, plus unformatted I/O.

Unsigned integers as implemented in gfortran are compatible with flang.

Here is a small, somewhat contrived example of their use:

    program main
      use iso_fortran_env, only : uint64
      unsigned(kind=uint64) :: v
      v = huge(v) - 32u_uint64
      print *,v
    end program main

which outputs the number 18446744073709551583.

Arithmetic operations work on unsigned integers, also for exponentiation. As an extension to J3/24-116.txt, unary minus and exponentiation of unsigned integers are permitted unless `-pedantic` is in force.

In intrinsic procedures, unsigned arguments are typically permitted for arguments for the data to be processed, analogous to the use of `REAL` arguments. Unsigned values are prohibited as index variables in `DO` loops and as array indices.

Unsigned numbers can be read and written using list-directed, formatted and unformatted I/O. For formatted I/O, the ‘`B`’, ‘`I`’, ‘`O`’ and ‘`Z`’ descriptors are valid. Negative values and values that would overflow are rejected with `-pedantic`.

`SELECT CASE` is supported for unsigned integers.

The following intrinsics take unsigned arguments:

- `BGE`, see `BGE` — Bitwise greater than or equal to
- `BGT`, see `BGT` — Bitwise greater than
- `BIT_SIZE`, see `BIT_SIZE` — Bit size inquiry function
- `BLE`, see `BLE` — Bitwise less than or equal to
- `BLT`, see `BLT` — Bitwise less than
- `CMPLX`, see `CMPLX` — Complex conversion function
- `CSHIFT`, see `CSHIFT` — Circular shift elements of an array
- `DIGITS`, see `DIGITS` — Significant binary digits function
- `DOT_PRODUCT`, see `DOT_PRODUCT` — Dot product function
- `DSHIFTL`, see `DSHIFTL` — Combined left shift
- `DSHIFTR`, see `DSHIFTR` — Combined right shift
- `EOSHIFT`, see `EOSHIFT` — End-off shift elements of an array
- `FINDLOC`, see `FINDLOC` — Search an array for a value
- `HUGE`, see `HUGE` — Largest number of a kind
- `IALL`, see `IALL` — Bitwise AND of array elements
- `IAND`, see `IAND` — Bitwise logical and
- `IANY`, see `IANY` — Bitwise OR of array elements
- `IBCLR`, see `IBCLR` — Clear bit
- `IBITS`, see `IBITS` — Bit extraction
- `IBSET`, see `IBSET` — Set bit
- `IEOR`, see `IEOR` — Bitwise logical exclusive or
- `INT`, see `INT` — Convert to integer type
- `IOR`, see `IOR` — Bitwise logical or
- `IPARITY`, see `IPARITY` — Bitwise XOR of array elements
- `ISHFT`, see `ISHFT` — Shift bits
- `ISHFTC`, see `ISHFTC` — Shift bits circularly
- `MATMUL`, see `MATMUL` — matrix multiplication
- `MAX`, see `MAX` — Maximum value of an argument list
- `MAXLOC`, see `MAXLOC` — Location of the maximum value within an array
- `MAXVAL`, see `MAXVAL` — Maximum value of an array
- `MERGE`, see `MERGE` — Merge variables
- `MERGE_BITS`, see `MERGE_BITS` — Merge of bits under mask
- `MIN`, see `MIN` — Minimum value of an argument list
- `MINLOC`, see `MINLOC` — Location of the minimum value within an array
- `MINVAL`, see `MINVAL` — Minimum value of an array
- `MOD`, see `MOD` — Remainder function
- `MODULO`, see `MODULO` — Modulo function
- `MVBITS`, see `MVBITS` — Move bits from one integer to another
- `NOT`, see `NOT` — Logical negation
- `OUT_OF_RANGE`, see `OUT_OF_RANGE` — Range check for numerical conversion
- `PRODUCT`, see `PRODUCT` — Product of array elements
- `RANDOM_NUMBER`, see `RANDOM_NUMBER` — Pseudo-random number
- `RANGE`, see `RANGE` — Decimal exponent range
- `REAL`, see `REAL` — Convert to real type
- `SHIFTA`, see `SHIFTA` — Right shift with fill
- `SHIFTL`, see `SHIFTL` — Left shift
- `SHIFTR`, see `SHIFTR` — Right shift
- `SUM`, see `SUM` — Sum of array elements
- `TRANSPOSE`, see `TRANSPOSE` — Transpose an array of rank two
- `TRANSFER`, see `TRANSFER` — Transfer bit patterns

The following intrinsics are enabled with `-funsigned`:

- `UINT`, see `UINT` – Convert to `UNSIGNED` type
- `UMASKL`, see `UMASKL` — Unsigned left justified mask
- `UMASKR`, see `UMASKR` — Unsigned right justified mask
- `SELECTED_UNSIGNED_KIND`, see `SELECTED_UNSIGNED_KIND` — Choose unsigned kind

The following constants have been added to the intrinsic `ISO_C_BINDING` module: `c_unsigned`, `c_unsigned_short`, `c_unsigned_char`, `c_unsigned_long`, `c_unsigned_long_long`, `c_uintmax_t`, `c_uint8_t`, `c_uint16_t`, `c_uint32_t`, `c_uint64_t`, `c_uint128_t`, `c_uint_fast8_t`, `c_uint_fast16_t`, `c_uint_fast32_t`, `c_uint_fast64_t`, `c_uint_fast128_t`, `c_uint_least8_t`, `c_uint_least16_t`, `c_uint_least32_t`, `c_uint_least64_t` and `c_uint_least128_t`.

The following constants have been added to the intrinsic `ISO_FORTRAN_ENV` module: `uint8`, `uint16`, `uint32` and `uint64`.