split std
This commit is contained in:
210
std/num.zr
Normal file
210
std/num.zr
Normal file
@@ -0,0 +1,210 @@
|
||||
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
|
||||
Reference in New Issue
Block a user