Skip to content

Numbers

Numbers in Harneet include integers and floating-point values with comprehensive instance methods for common mathematical operations.

Overview

Harneet provides: - Integers - whole numbers with various sizes (int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr) - Floats - decimal numbers (float32, float64) - Method-rich - built-in .abs(), .min(), .max(), .clamp(), .toString() for integers; additional .round(), .floor(), .ceil(), .isNaN(), .isInf() for floats - Type-safe - strict type checking with explicit conversions

Integer Types

Fixed-size Signed Integers

  • int - Platform-dependent (32 or 64-bit)
  • int8 - 8-bit signed (-128 to 127)
  • int16 - 16-bit signed (-32,768 to 32,767)
  • int32 - 32-bit signed (-2,147,483,648 to 2,147,483,647)
  • int64 - 64-bit signed (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)

Fixed-size Unsigned Integers

  • uint - Platform-dependent (32 or 64-bit)
  • uint8 - 8-bit unsigned (0 to 255)
  • uint16 - 16-bit unsigned (0 to 65,535)
  • uint32 - 32-bit unsigned (0 to 4,294,967,295)
  • uint64 - 64-bit unsigned (0 to 18,446,744,073,709,551,615)
  • uintptr - Unsigned integer large enough to hold a pointer

Arbitrary-precision Integers

  • bigint - Arbitrary-precision signed integer backed by math/big.Int.

bigint is useful when your values can exceed 64-bit ranges or when you need exact integer math independent of machine word size.

You construct bigint values with the global bigint(...) function:

bigint constructor
package main
import fmt

// From decimal strings
var a bigint = bigint("123456789012345678901234567890")
var b bigint = bigint("-42")

// From hex and binary strings
var hex bigint = bigint("0xff")      // 255
var negHex bigint = bigint("-0x10")  // -16
var bin bigint = bigint("0b1010")    // 10
var negBin bigint = bigint("-0b11")  // -3

// From fixed-size integers
var i int = 42
var j int64 = -100
var bi bigint = bigint(i)
var bj bigint = bigint(j)

fmt.Println(a, b, hex, bin, bi, bj)

Constructor rules:

  • Accepted inputs:
  • Fixed-size integer families: int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr.
  • Strings containing an optional sign followed by:

    • Decimal digits, e.g. "123", "-42".
    • Hex with 0x / 0X prefix, e.g. "0xff", "-0x10".
    • Binary with 0b / 0B prefix, e.g. "0b1010", "-0b11".
  • Rejected inputs:

  • Floats (float32, float64).
  • Booleans.
  • Empty strings or strings without digits after an optional sign or prefix.
  • Non-integer strings like "12.3", "0x", "0b".

Invalid inputs cause runtime errors with descriptive messages.

Arbitrary-precision Decimals

  • bigdecimal - Arbitrary-precision decimal/rational number backed by math/big.Rat.

bigdecimal is useful when you need exact decimal math (for example, money, interest rates, or fractions like 1/3) without binary floating-point rounding error.

You construct bigdecimal values with the global bigdecimal(...) function:

bigdecimal constructor
package main
import fmt

// From integers and floats
var a bigdecimal = bigdecimal(42)
var b bigdecimal = bigdecimal(3.5)

// From decimal strings
var c bigdecimal = bigdecimal("0.1")
var d bigdecimal = bigdecimal("-2.75")

// From rational strings (numerator/denominator)
var ratio bigdecimal = bigdecimal("1/3")

fmt.Println(a, b, c, d, ratio)

Constructor rules:

  • Accepted inputs:
  • Fixed-size integers: int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr.
  • float32, float64 (converted via Go's big.Rat.SetFloat64, which may round when necessary).
  • Strings containing an optional sign and one of:
    • Decimal form, e.g. "0.1", "-2.75".
    • Rational form p/q, e.g. "1/3", "-22/7".
  • Rejected inputs:
  • Booleans.
  • Empty strings or malformed numeric/rational strings.

Invalid inputs cause runtime errors with descriptive messages.

bigdecimal supports the same arithmetic operators as fixed-size numbers, but only in same-type operations:

  • bigdecimal + bigdecimal, -, *, /, %, </, **

Division (/) produces an exact rational result. Floor division (</) and modulo (%) follow the identity:

a = q * b + r,  where  q = floor(a / b)

bigdecimal also provides instance methods mirroring integers and floats:

  • .abs(), .min(other), .max(other), .clamp(min, max), .toString()

Float Types

  • float32 - 32-bit IEEE-754 floating point
  • float64 - 64-bit IEEE-754 floating point (default for float literals)

Integer Instance Methods

All integer methods return values of the same type as the receiver.

abs()

Returns the absolute value:

abs()
1
2
3
4
5
6
package main
var negative = -42
var positive = negative.abs()  // 42

var alreadyPositive = 10
var unchanged = alreadyPositive.abs()  // 10

min(other)

Returns the minimum of two integers:

min()
1
2
3
4
5
6
7
package main
var a = 10
var b = 20
var minimum = a.min(b)  // 10

var c = -5
var minimum2 = a.min(c)  // -5

max(other)

Returns the maximum of two integers:

max()
1
2
3
4
5
6
7
package main
var a = 10
var b = 20
var maximum = a.max(b)  // 20

var c = -5
var maximum2 = a.max(c)  // 10

clamp(min, max)

Restricts the value to be within the specified range:

clamp()
1
2
3
4
5
6
7
8
9
package main
var value = 15
var clamped = value.clamp(0, 10)  // 10 (15 > 10, so clamped to max)

var value2 = -5
var clamped2 = value2.clamp(0, 10)  // 0 (-5 < 0, so clamped to min)

var value3 = 5
var clamped3 = value3.clamp(0, 10)  // 5 (within range, unchanged)

toString()

Converts the integer to a string:

toString()
1
2
3
4
5
6
package main
var num = 42
var str = num.toString()  // "42"

var negative = -17
var negStr = negative.toString()  // "-17"

Float Instance Methods

All float methods return float64 values.

abs()

Returns the absolute value:

abs()
1
2
3
package main
var negative = -3.14
var positive = negative.abs()  // 3.14

min(other)

Returns the minimum of two floats:

min()
1
2
3
4
package main
var a = 1.5
var b = 2.5
var minimum = a.min(b)  // 1.5

max(other)

Returns the maximum of two floats:

max()
1
2
3
4
package main
var a = 1.5
var b = 2.5
var maximum = a.max(b)  // 2.5

clamp(min, max)

Restricts the value to be within the specified range:

clamp()
1
2
3
4
5
6
package main
var value = 3.7
var clamped = value.clamp(0.0, 3.0)  // 3.0

var value2 = -0.5
var clamped2 = value2.clamp(0.0, 1.0)  // 0.0

round()

Rounds to the nearest integer value:

round()
1
2
3
4
5
6
7
8
9
package main
var pi = 3.14159
var rounded = pi.round()  // 3.0

var higher = 3.6
var rounded2 = higher.round()  // 4.0

var negative = -2.5
var rounded3 = negative.round()  // -3.0 (rounds to even)

floor()

Rounds down to the nearest integer:

floor()
1
2
3
4
5
6
package main
var value = 3.9
var floored = value.floor()  // 3.0

var negative = -2.1
var floored2 = negative.floor()  // -3.0

ceil()

Rounds up to the nearest integer:

ceil()
1
2
3
4
5
6
package main
var value = 3.1
var ceiled = value.ceil()  // 4.0

var negative = -2.9
var ceiled2 = negative.ceil()  // -2.0

isNaN()

Checks if the value is Not-a-Number:

isNaN()
1
2
3
4
5
6
7
8
package main
var normal = 3.14
var notNaN = normal.isNaN()  // false

// NaN can result from invalid operations
var zero = 0.0
var invalid = zero / zero
var isNaN = invalid.isNaN()  // true

isInf()

Checks if the value is positive or negative infinity:

isInf()
1
2
3
4
5
6
7
8
9
package main
var normal = 3.14
var notInf = normal.isInf()  // false

// Infinity can result from overflow or division by zero
var one = 1.0
var zero = 0.0
var infinite = one / zero
var isInf = infinite.isInf()  // true

toString()

Converts the float to a string:

toString()
1
2
3
4
5
6
package main
var pi = 3.14159
var str = pi.toString()  // "3.14159" (uses %g format)

var whole = 42.0
var wholeStr = whole.toString()  // "42" (no unnecessary decimals)

None-Receiver Safety

All number instance methods enforce None-receiver safety. Calling a method on None raises a runtime error:

None-Receiver Safety
1
2
3
4
5
6
package main
var num int = None

// All of these will raise runtime errors:
// num.abs()      // ERROR: type null does not have method 'abs'
// num.toString() // ERROR: type null does not have method 'toString'

Number Literals

Number Literals
package main
// Integers
var decimal = 42
var hex = 0x2A        // 42 in hexadecimal
var binary = 0b101010 // 42 in binary
var negative = -17

// Floats
var pi = 3.14159
var scientific = 1.23e-4  // 0.000123
var negative_float = -2.71

Complete Example

Complete Example - Integers
package main
import fmt

var num = -42

// Integer methods
fmt.Println("Absolute value:", num.abs())  // 42

var a = 10
var b = 20
fmt.Println("Min:", a.min(b))  // 10
fmt.Println("Max:", a.max(b))  // 20

var value = 15
fmt.Println("Clamped:", value.clamp(0, 10))  // 10

fmt.Println("As string:", num.toString())  // "-42"
Complete Example - Floats
package main
import fmt

var pi = 3.14159

// Float methods
fmt.Println("Absolute:", (-pi).abs())  // 3.14159
fmt.Println("Rounded:", pi.round())    // 3.0
fmt.Println("Floor:", pi.floor())      // 3.0
fmt.Println("Ceil:", pi.ceil())        // 4.0

var a = 1.5
var b = 2.5
fmt.Println("Min:", a.min(b))  // 1.5
fmt.Println("Max:", a.max(b))  // 2.5

var value = 3.7
fmt.Println("Clamped:", value.clamp(0.0, 3.0))  // 3.0

// Special value checks
var normal = 3.14
fmt.Println("Is NaN:", normal.isNaN())   // false
fmt.Println("Is Inf:", normal.isInf())   // false

fmt.Println("As string:", pi.toString())  // "3.14159"

Use Cases

Value Validation

Value Validation
1
2
3
package main
var userAge = -5
var validAge = userAge.abs().clamp(0, 120)

Range Constraints

Range Constraints
1
2
3
package main
var brightness = 150
var validBrightness = brightness.clamp(0, 100)  // 100

Rounding Calculations

Rounding Calculations
1
2
3
4
package main
var price = 19.99
var wholeDollars = price.floor()  // 19.0
var roundedPrice = price.round()  // 20.0

String Conversion

String Conversion
1
2
3
package main
var score = 95
var message = "Your score is: " + score.toString()

See Also