diff --git a/docs/type.rst b/docs/type.rst index 0f01ec8745852..53263967ddcae 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -1,8 +1,33 @@ Type system =========== +Taichi supports common numerical data types. Each type is denoted as +a character indicating its *category* and a number of *precision bits*, e.g., ``i32`` and ``f64``. + +The *category* can be one of: + +- ``i`` for signed integers, e.g. 233, -666 +- ``u`` for unsigned integers, e.g. 233, 666 +- ``f`` for floating point numbers, e.g. 2.33, 1e-4 + +The *digital number* can be one of: + +- ``8`` +- ``16`` +- ``32`` +- ``64`` + +It represents how many **bits** are used in storing the data. +The larger the bit number, the higher the precision is. + +For example, the two most commonly used types: + +- ``i32`` represents a 32-bit signed integer. +- ``f32`` represents a 32-bit floating pointer number. + Supported types --------------- + Currently, supported basic types in Taichi are - int8 ``ti.i8`` @@ -46,13 +71,21 @@ Currently, supported basic types in Taichi are (OK: supported, EXT: require extension, N/A: not available) -Boolean types should be represented using ``ti.i32``. +.. note:: + + Boolean types are represented using ``ti.i32``. + -Binary operations on different types will give you a promoted type, following the C programming language, e.g. -- ``i32 + f32 = f32`` -- ``f32 + f64 = f64`` -- ``i32 + i64 = i64`` +Type promotion +-------------- + +Binary operations on different types will give you a promoted type, following the C programming language convention, e.g.: + +- ``i32 + f32 = f32`` (integer + float = float) +- ``i32 + i64 = i64`` (less-bits + more-bits = more-bits) + +Basically it will try to choose the more precise type to contain the result value. .. _default_precisions: @@ -60,40 +93,109 @@ Binary operations on different types will give you a promoted type, following th Default precisions ------------------ -By default, numerical literals have 32-bit precisions. +By default, all numerical literals have 32-bit precisions. For example, ``42`` has type ``ti.i32`` and ``3.14`` has type ``ti.f32``. + Default integer and float-point precisions (``default_ip`` and ``default_fp``) can be specified when initializing Taichi: .. code-block:: python - ti.init(..., default_fp=ti.f32) - ti.init(..., default_fp=ti.f64) + ti.init(default_fp=ti.f32) + ti.init(default_fp=ti.f64) + + ti.init(default_ip=ti.i32) + ti.init(default_ip=ti.i64) + + +Also note that you may use ``float`` or ``int`` in type definitions as aliases +for default precisions, e.g.: + +.. code-block:: python + + ti.init(default_ip=ti.i64, default_fp=ti.f32) + + x = ti.var(float, 5) + y = ti.var(int, 5) + # is equivalent to: + x = ti.var(ti.f32, 5) + y = ti.var(ti.i64, 5) + + def func(a: float) -> int: + ... + + # is equivalent to: + def func(a: ti.f32) -> ti.i64: + ... - ti.init(..., default_ip=ti.i32) - ti.init(..., default_ip=ti.i64) Type casts ---------- -Use ``ti.cast`` to cast scalar values. +Implicit casts +************** + +.. warning:: + + The type of a variable is **determinated on it's initialization**. + +When a *low-precision* variable is assigned to a *high-precision* variable, it will be +implicitly promoted to the *wide* type and no warning will be raised: + +.. code-block:: python + + a = 1.7 + a = 1 + print(a) # 1.0 + +When a *high-precision* variable is assigned to a *low-precision* type, it will be +implicitly down-cast into the *low-precision* type and Taichi will raise a warning: .. code-block:: python - a = 1.4 - b = ti.cast(a, ti.i32) - c = ti.cast(b, ti.f32) + a = 1 + a = 1.7 + print(a) # 1 + +Explicit casts +************** + +You may use ``ti.cast`` to explicitly cast scalar values between different types: + +.. code-block:: python - # Equivalently, use ``int()`` and ``float()`` - # to convert values to default float-point/integer types - b = int(a) - c = float(b) + a = 1.7 + b = ti.cast(a, ti.i32) # 1 + c = ti.cast(b, ti.f32) # 1.0 - # Element-wise casts in matrices - mat = ti.Matrix([[3.0, 0.0], [0.3, 0.1]]) - mat_int = mat.cast(int) - mat_int2 = mat.cast(ti.i32) +Equivalently, use ``int()`` and ``float()`` to convert values to float-point or +integer types of default precisions: + +.. code-block:: python + + a = 1.7 + b = int(a) # 1 + c = float(a) # 1.0 + +Casting vectors and matrices +**************************** + +Type casts applied to vectors/matrices are element-wise: + +.. code-block:: python + + u = ti.Vector([2.3, 4.7]) + v = int(u) # ti.Vector([2, 4]) + # If you are using ti.i32 as default_ip, this is equivalent to: + v = ti.cast(u, ti.i32) # ti.Vector([2, 4]) + +Bit casting +*********** Use ``ti.bit_cast`` to bit-cast a value into another data type. The underlying bits will be preserved in this cast. The new type must have the same width as the the old type. For example, bit-casting ``i32`` to ``f64`` is not allowed. Use this operation with caution. + +.. code-block:: + + For people from C++, ``ti.bit_cast`` is equivalent to ``reinterpret_cast``.