Type ‣ Int ᴾᴴᴾ - chung-leong/zigar GitHub Wiki

JavaScript | PHP


In Zig, there are two varieties of integers: signed and unsigned. The former has the prefix i and is used when negative values are possible. The latter has the prefix u and is used when a variable is always positive. Integers in Zig have arbitrary bit-size (up to 65535). Ones that are 64-bit or smaller are represented in PHP as int. Those larger than 64-bit are represented as GMP objects provided the extension is active.

pub fn getInt32(number: i32) i32 {
    return number;
}

pub fn getInt33(number: i33) i33 {
    return number;
}

pub fn getInt256(number: i256) i256 {
    return number;
}
<?php

$m = zigar_use(__DIR__ . '/int-example-1.zig');

debug_zval_dump($m->getInt32(1234));
debug_zval_dump($m->getInt33(1234));
debug_zval_dump($m->getInt256(1234));
int(1234)
int(1234)
object(GMP)#15 (1) refcount(1){
  ["num"]=>
  string(4) "1234" refcount(1)
}

Range checking

When runtime safety is active (i.e. when optimize is Debug or ReleaseSafe), values exceeding a type's range will cause an exception to be thrown on the PHP side.

const std = @import("std");

pub fn print8(number: i8) void {
    std.debug.print("number = {d}\n", .{number});
}
<?php

$m = zigar_use(__DIR__ . '/int-example-3.zig', [ 'optimize' => 'Debug' ]);

try {
   $m->print8(128);
} catch (Exception $e) {
   echo $e->getMessage(), "\n";
}
args[0]: Int8 cannot represent the value given: 128

When runtime safety is off, an integer overflow would not cause an error. The value would simply wrap around:

<?php

$m = zigar_use(__DIR__ . '/int-example-3.zig', [ 'optimize' => 'ReleaseSmall' ]);

$m->print8(128);
-128

In packed struct

Integers smaller than 8-bit like u2 or u4 are typically only used in packed struct. Using only as many bits as necessary for the range required helps reduce the size of data structures.

pub const UserPreferences = packed struct {
    option1: bool = false,
    option2: u2 = 0,
    option3: u3 = 0,
    option4: u4 = 0,
    option5: bool = false,
    option6: bool = false,
    option7: u2 = 0,
    option8: u2 = 0,
};
<?php 

$m = zigar_use(__DIR__ . '/int-example-4.zig');

$pref = new $m->UserPreferences(
    option2: 2,
    option3: 7,
    option4: 15,
    option7: 1,
    option8: 3,
);

print_r($pref);
echo "size = " . strlen($pref->__bytes) . "\n";
UserPreferences Object
(
    [option1] => 
    [option2] => 2
    [option3] => 7
    [option4] => 15
    [option5] => 
    [option6] => 
    [option7] => 1
    [option8] => 3
)
size = 2

Types