include "std/core.zr" func i64.abs[n: i64] : i64 if n == -9223372036854775808 panic("MIN_I64 passed to math.abs") if n < 0 return -n return n func i64.sign[n: i64] : i64 if n < 0 return -1 else if n > 0 return 1 else return 0 func i64.isqrt[n: i64] : i64 if n < 0 panic("negative number passed to math.isqrt") if n == 0 || n == 1 return n guess := n next_guess := (guess + n / guess) / 2 while next_guess < guess guess = next_guess next_guess = (guess + n / guess) / 2 return guess func i64.is_prime[n: i64]: bool if n <= 1 return false if n == 2 || n == 3 return true if n % 2 == 0 || n % 3 == 0 return false i := 5 while i * i <= n if n % i == 0 || n % (i + 2) == 0 return false i += 6 return true func i64.to_str_buf[n: i64, buf: ptr] : void if n == 0 buf[0] = '0' buf[1] = 0 return neg : bool = n < 0 if neg // MIN_I64 will fail but i so dont care n = -n tmp := _stackalloc(21) end := 20 tmp[end] = 0 end -= 1 for i in 0..19 if n == 0 break tmp[end] = '0' + (n % 10) n = n / 10 end -= 1 if neg tmp[end] = '-' end -= 1 len := 19 - end for i in 0..len buf[i] = tmp[end + 1 + i] buf[len] = 0 func i64.to_hex_str_buf[n: i64, buf: ptr] : void hex_chars := "0123456789abcdef" if n == 0 buf[0] = '0' buf[1] = 0 return mask := (1 << 60) - 1 tmp := _stackalloc(17) len := 0 for i in 0..16 if n == 0 break tmp[len] = hex_chars[n & 15] n = (n >> 4) & mask len += 1 for j in 0..len buf[j] = tmp[len - 1 - j] buf[len] = 0 func f64.to_str_buf[x: i64, buf: ptr] : void bits := x sign := (bits >> 63) & 1 exp := (bits >> 52) & 0x7ff mant := bits & 0x000fffffffffffff if exp == 0x7ff panic("invalid float") p := 0 if sign buf[p] = '-' p += 1 bits = bits & 0x7fffffffffffffff if exp == 0 && mant == 0 buf[p] = '0' buf[p+1] = '.' buf[p+2] = '0' buf[p+3] = 0 return sig := mant if exp != 0 sig = sig | 0x0010000000000000 shift := exp - 1075 if shift >= 0 (sig << shift)->to_str_buf(buf + p) while buf[p] p += 1 buf[p] = '.' buf[p+1] = '0' buf[p+2] = 0 return ns := -shift if ns <= 52 int_part := sig >> ns int_part->to_str_buf(buf + p) while buf[p] p += 1 else buf[p] = '0' p += 1 buf[p] = '.' p += 1 mask := (1 << ns) - 1 frac := sig & mask for i in 0..6 if frac == 0 if i > 0 break buf[p] = '0' p += 1 break frac = frac * 10 digit := frac >> ns buf[p] = '0' + digit as u8 p += 1 frac = frac & mask buf[p] = 0 func math.gcd[a: i64, b: i64] : i64 a = a->abs() b = b->abs() while b != 0 tmp := b b = a % b a = tmp return a func math.min[a: i64, b: i64] : i64 if a < b return a return b func math.max[a: i64, b: i64] : i64 if a > b return a return b func math.pow[b: i64, e: i64] : i64 if e < 0 panic("negative exponent passed to math.pow") out := 1 while e > 0 if e & 1 out = out * b b = b * b e = e >> 1 return out func math.lcm[a: i64, b: i64] : i64 return (a / math.gcd(a, b)) * b func math.octal_to_decimal[octal: i64] : i64 decimal := 0 base := 1 while octal > 0 digit := octal % 10 decimal += digit * base base = base * 8 octal = octal / 10 return decimal