int_operations.rst 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. .. _int-ops:
  2. Native integer operations
  3. =========================
  4. Mypyc supports these integer types:
  5. * ``int`` (arbitrary-precision integer)
  6. * ``i64`` (64-bit signed integer)
  7. * ``i32`` (32-bit signed integer)
  8. * ``i16`` (16-bit signed integer)
  9. * ``u8`` (8-bit unsigned integer)
  10. ``i64``, ``i32``, ``i16`` and ``u8`` are *native integer types* and
  11. are available in the ``mypy_extensions`` module. ``int`` corresponds
  12. to the Python ``int`` type, but uses a more efficient runtime
  13. representation (tagged pointer). Native integer types are value types.
  14. All integer types have optimized primitive operations, but the native
  15. integer types are more efficient than ``int``, since they don't
  16. require range or bounds checks.
  17. Operations on integers that are listed here have fast, optimized
  18. implementations. Other integer operations use generic implementations
  19. that are generally slower. Some operations involving integers and other
  20. types, such as list indexing, are documented elsewhere.
  21. Construction
  22. ------------
  23. ``int`` type:
  24. * Integer literal
  25. * ``int(x: float)``
  26. * ``int(x: i64)``
  27. * ``int(x: i32)``
  28. * ``int(x: i16)``
  29. * ``int(x: u8)``
  30. * ``int(x: str)``
  31. * ``int(x: str, base: int)``
  32. * ``int(x: int)`` (no-op)
  33. ``i64`` type:
  34. * ``i64(x: int)``
  35. * ``i64(x: float)``
  36. * ``i64(x: i64)`` (no-op)
  37. * ``i64(x: i32)``
  38. * ``i64(x: i16)``
  39. * ``i64(x: u8)``
  40. * ``i64(x: str)``
  41. * ``i64(x: str, base: int)``
  42. ``i32`` type:
  43. * ``i32(x: int)``
  44. * ``i32(x: float)``
  45. * ``i32(x: i64)`` (truncate)
  46. * ``i32(x: i32)`` (no-op)
  47. * ``i32(x: i16)``
  48. * ``i32(x: u8)``
  49. * ``i32(x: str)``
  50. * ``i32(x: str, base: int)``
  51. ``i16`` type:
  52. * ``i16(x: int)``
  53. * ``i16(x: float)``
  54. * ``i16(x: i64)`` (truncate)
  55. * ``i16(x: i32)`` (truncate)
  56. * ``i16(x: i16)`` (no-op)
  57. * ``i16(x: u8)``
  58. * ``i16(x: str)``
  59. * ``i16(x: str, base: int)``
  60. Conversions from ``int`` to a native integer type raise
  61. ``OverflowError`` if the value is too large or small. Conversions from
  62. a wider native integer type to a narrower one truncate the value and never
  63. fail. More generally, operations between native integer types don't
  64. check for overflow.
  65. Implicit conversions
  66. --------------------
  67. ``int`` values can be implicitly converted to a native integer type,
  68. for convenience. This means that these are equivalent::
  69. from mypy_extensions import i64
  70. def implicit() -> None:
  71. # Implicit conversion of 0 (int) to i64
  72. x: i64 = 0
  73. def explicit() -> None:
  74. # Explicit conversion of 0 (int) to i64
  75. x = i64(0)
  76. Similarly, a native integer value can be implicitly converted to an
  77. arbitrary-precision integer. These two functions are equivalent::
  78. def implicit(x: i64) -> int:
  79. # Implicit conversion from i64 to int
  80. return x
  81. def explicit(x: i64) -> int:
  82. # Explicit conversion from i64 to int
  83. return int(x)
  84. Operators
  85. ---------
  86. * Arithmetic (``+``, ``-``, ``*``, ``//``, ``/``, ``%``)
  87. * Bitwise operations (``&``, ``|``, ``^``, ``<<``, ``>>``, ``~``)
  88. * Comparisons (``==``, ``!=``, ``<``, etc.)
  89. * Augmented assignment (``x += y``, etc.)
  90. If one of the above native integer operations overflows or underflows
  91. with signed operands, the behavior is undefined. Signed native integer
  92. types should only be used if all possible values are small enough for
  93. the type. For this reason, the arbitrary-precision ``int`` type is
  94. recommended for signed values unless the performance of integer
  95. operations is critical.
  96. Operations on unsigned integers (``u8``) wrap around on overflow.
  97. It's a compile-time error to mix different native integer types in a
  98. binary operation such as addition. An explicit conversion is required::
  99. from mypy_extensions import i64, i32
  100. def add(x: i64, y: i32) -> None:
  101. a = x + y # Error (i64 + i32)
  102. b = x + i64(y) # OK
  103. You can freely mix a native integer value and an arbitrary-precision
  104. ``int`` value in an operation. The native integer type is "sticky"
  105. and the ``int`` operand is coerced to the native integer type::
  106. def example(x: i64, y: int) -> None:
  107. a = x * y
  108. # Type of "a" is "i64"
  109. ...
  110. b = 1 - x
  111. # Similarly, type of "b" is "i64"
  112. Statements
  113. ----------
  114. For loop over a range is compiled efficiently, if the ``range(...)`` object
  115. is constructed in the for statement (after ``in``):
  116. * ``for x in range(end)``
  117. * ``for x in range(start, end)``
  118. * ``for x in range(start, end, step)``
  119. If one of the arguments to ``range`` in a for loop is a native integer
  120. type, the type of the loop variable is inferred to have this native
  121. integer type, instead of ``int``::
  122. for x in range(i64(n)):
  123. # Type of "x" is "i64"
  124. ...