# Does TypePHP Automatically Wrap Long Numeric Literals into High-Precision Types?

> Discover if TypePHP wraps long numeric literals into high-precision types. Learn how TypePHP automatically promotes numbers exceeding 64-bit integer limits to BigInt, Decimal, or BigFloat.

- Repository: [Swoole Project/typephp](https://github.com/swoole/typephp)
- Tags: deep-dive
- Published: 2026-08-30

---

**Yes. When a numeric literal exceeds the signed 64-bit integer range, TypePHP's compiler automatically promotes it to a high-precision type such as `BigInt`, `Decimal`, or `BigFloat` during the constant-expression evaluation phase.**

TypePHP, an open-source project available in the `swoole/typephp` repository, extends PHP with strict typing and high-precision arithmetic capabilities. The compiler detects overflowing numeric literals at parse time and seamlessly rewrites them to appropriate high-precision representations without requiring explicit type annotations from developers.

## How TypePHP Detects Overflowing Numeric Literals

### The 64-Bit Integer Threshold

TypePHP operates with a clear boundary for automatic promotion. Any integer literal that cannot fit within the standard `php::Int` type—specifically, values outside the signed 64-bit range (−2⁶³ to 2⁶³−1)—triggers the high-precision wrapping mechanism. For example, the literal `9223372036854775808` (2⁶³) exceeds PHP's native integer maximum and is automatically handled as a `BigInt`.

### Constant-Expression Evaluation Phase

The detection logic resides in **[`src/CompilerBase.php`](https://github.com/swoole/typephp/blob/main/src/CompilerBase.php)**, where the compiler performs constant folding and literal analysis. According to the source code comments around line 1450, the system checks if a numeric literal's raw value represents an integer that exceeds the int64 range. If the check fails—meaning the literal cannot be parsed as a standard 64-bit signed integer—the compiler immediately rewrites the node to use the high-precision alternative defined in **[`src/Type.php`](https://github.com/swoole/typephp/blob/main/src/Type.php)**.

## High-Precision Types in TypePHP

TypePHP defines three primary high-precision types to handle literals that surpass native PHP limits:

- **`BigInt`** (`php::BigInt`): Applied to integer literals exceeding the 64-bit range. This is the most common automatic promotion scenario.
- **`Decimal`** (`php::Decimal`): Used for decimal literals containing many fractional digits or scales that cannot be represented accurately by standard floats.
- **`BigFloat`** (`php::BigFloat`): Assigned to floating-point literals that exceed the range or precision of native PHP floats.

These constants are declared in **[`src/Type.php`](https://github.com/swoole/typephp/blob/main/src/Type.php)**, which serves as the central registry for both primitive and high-precision type definitions.

## Code Examples of Automatic Type Promotion

When writing TypePHP code, developers can use literal syntax naturally. The compiler handles the type promotion transparently:

```php
<?php
// Normal 64-bit integer – stays as php::Int
$small = 12345;               // type: php::Int

// Integer larger than 2⁶³−1 – automatically becomes php::BigInt
$huge  = 9223372036854775808; // type: php::BigInt

// Mixed arithmetic – the smaller operand is auto-converted
$sum = $huge + 1;             // BigInt + Int → result type php::BigInt

// Decimal literal with high precision – becomes php::Decimal
$precise = 0.12345678901234567890; // type: php::Decimal

// Float beyond native range – becomes php::BigFloat
$veryBig = 1.8e308;          // type: php::BigFloat

```

In the generated TypePHP intermediate representation (IR), the automatic conversion is explicit:

```text
%1 = const_int 12345                     ; php::Int
%2 = const_bigint "9223372036854775808" ; php::BigInt
%3 = add %2, const_int 1                 ; php::BigInt (auto-converted)
%4 = const_decimal "0.12345678901234567890"
%5 = const_bigfloat "1.8e308"

```

## Source Code Implementation Details

The automatic wrapping behavior is grounded in specific source files within the `swoole/typephp` repository:

- **[`src/CompilerBase.php`](https://github.com/swoole/typephp/blob/main/src/CompilerBase.php)** (line ≈ 1450): Contains the overflow detection logic that triggers auto-wrapping during constant-expression evaluation.
- **[`src/Type.php`](https://github.com/swoole/typephp/blob/main/src/Type.php)**: Defines the `BIGINT`, `DECIMAL`, and `BIGFLOAT` constants that the compiler uses when rewriting literals.
- **[`docs/en/HIGH_PRECISION_TYPES.md`](https://github.com/swoole/typephp/blob/main/docs/en/HIGH_PRECISION_TYPES.md)**: Provides human-readable documentation describing the automatic literal conversion rules and high-precision type semantics.
- **`tests/compiler/bigint/bigint_types.phpt`**: Validates that simple integer literals over the 64-bit limit are treated as `BigInt`.
- **`tests/compiler/bigint/both_types.phpt`**: Confirms automatic promotion behavior in mixed `BigInt` and `Int` arithmetic operations.

## Summary

- TypePHP automatically promotes numeric literals exceeding the signed 64-bit integer range to `BigInt` during compilation.
- The detection occurs in **[`src/CompilerBase.php`](https://github.com/swoole/typephp/blob/main/src/CompilerBase.php)** during the constant-expression evaluation phase, requiring no manual intervention.
- Three high-precision types are available: `BigInt` for large integers, `Decimal` for high-precision decimals, and `BigFloat` for extended-range floats.
- Mixed operations between standard integers and high-precision types automatically convert the standard integer to the high-precision type to prevent overflow.
- Test files in **`tests/compiler/bigint/`** verify the automatic wrapping behavior.

## Frequently Asked Questions

### What is the cutoff for automatic BigInt promotion in TypePHP?

The cutoff is the signed 64-bit integer limit (2⁶³−1 or 9,223,372,036,854,775,807). Any integer literal larger than this value, or smaller than −2⁶³, automatically becomes a `BigInt` according to the overflow check in **[`src/CompilerBase.php`](https://github.com/swoole/typephp/blob/main/src/CompilerBase.php)**.

### Do I need to manually cast literals to BigInt in TypePHP?

No. TypePHP eliminates the need for explicit casting of large numeric literals. The compiler inspects the raw string value of literals during parsing and automatically assigns the appropriate high-precision type when native PHP integer or float types are insufficient.

### How does TypePHP handle mixed operations between Int and BigInt?

When performing arithmetic between a `BigInt` and a standard `Int`, TypePHP automatically converts the `Int` operand to `BigInt` to maintain precision. As demonstrated in **`tests/compiler/bigint/both_types.phpt`**, the result type of such operations is always the higher-precision `BigInt` type.

### Where are the high-precision type constants defined?

The constants `BIGINT`, `DECIMAL`, and `BIGFLOAT` are defined in **[`src/Type.php`](https://github.com/swoole/typephp/blob/main/src/Type.php)**. This file serves as the authoritative source for type definitions used by the compiler when rewriting numeric literals that exceed standard PHP limits.