Documentation
¶
Overview ¶
Package i128 provides a signed 128-bit integer.
It exists for one reason: `sum` of an integer column must not silently overflow. Summing a thousand Int8 values overflows an Int8 almost immediately, and a wrapped sum is a plausible-looking wrong number that nothing downstream can detect. ursus follows DuckDB and accumulates integer sums at 128 bits, where overflow is unreachable for any real dataset: even Int64 values at the maximum magnitude would need 2^63 rows to overflow.
The type is deliberately small and total. It has no division and no modulo — 128-bit division needs Knuth algorithm D and `sum(x) % 7` is not a query anyone writes. Division is available by casting to Int64 or Float64 first.
Index ¶
- Variables
- type Int128
- func (a Int128) Add(b Int128) Int128
- func (a Int128) AppendBigEndian(dst []byte) []byte
- func (a Int128) Cmp(b Int128) int
- func (a Int128) Float64() float64
- func (a Int128) GoString() string
- func (a Int128) Int64() (int64, bool)
- func (a Int128) IsZero() bool
- func (a Int128) Neg() Int128
- func (a Int128) Sign() int
- func (a Int128) String() string
- func (a Int128) Sub(b Int128) Int128
- func (a Int128) Uint64() (uint64, bool)
Constants ¶
This section is empty.
Variables ¶
var ( Zero = Int128{} One = Int128{0, 1} Min = Int128{Hi: math.MinInt64, Lo: 0} Max = Int128{Hi: math.MaxInt64, Lo: math.MaxUint64} )
Common values.
Functions ¶
This section is empty.
Types ¶
type Int128 ¶
Int128 is a signed 128-bit integer in two's complement.
Hi carries the sign; Lo is the unsigned low half. The zero value is 0.
It is comparable, so it can be a map key, and it is 16 bytes with no pointers, so a column of them is a flat SIMD-friendly buffer like any other numeric type.
func FromFloat64 ¶
FromFloat64 truncates toward zero. ok is false if v is NaN, infinite, or outside the Int128 range.
func FromUint64 ¶
FromUint64 zero-extends a uint64.
Every uint64 fits in an Int128 with room to spare, which is why unsigned sums can share the signed accumulator — and incidentally why widening to 128 bits dissolves the Uint64/Int64 promotion problem that otherwise has no answer.
func (Int128) Add ¶
Add returns a+b, wrapping on overflow.
Wrapping is safe here in a way it is not at 64 bits: reaching 2^127 requires summing 2^63 values of maximum magnitude, so the accumulator cannot overflow on any input that fits in memory. Callers that narrow the result to a smaller type do check — see Int64.
func (Int128) AppendBigEndian ¶
AppendBigEndian appends the 16-byte big-endian two's-complement encoding, with the sign bit flipped so that the byte ordering matches the value ordering. This is the form the group-key encoder and any future spill file use.
func (Int128) Int64 ¶
Int64 narrows to an int64. ok is false if the value does not fit.
The check is the point: this is the boundary where a 128-bit accumulator becomes a user-visible number, and it is where an overflow that was impossible internally must be reported rather than truncated.
func (Int128) Neg ¶
Neg returns -a. Neg(Min) is Min, matching two's complement at every other width.