Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
246 changes: 245 additions & 1 deletion Math.ark
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,234 @@
# @author https://github.com/SuperFola
(let NaN builtin__math:NaN)

# @brief Count the number of '1' bits in the given value
# @param value the Number, must be an integer
# =begin
# (math:countOnes 5) # 2
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let countOnes (fun (_x) (builtin__math:countOnes _x)))

# @brief Count the number of '0' bits in the given value
# @param value the Number, must be an integer
# =begin
# (math:countZeros 5) # 1
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let countZeros (fun (_x) (builtin__math:countZeros _x)))

# @brief Invert a number on 64 bits
# @param value Number, must be an integer
# =begin
# (math:bitNot 5) # -6
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let bitNot (fun (_x) (builtin__math:bitNot _x)))

# @brief Bitwise and
# @param lhs Number, must be an integer
# @param rhs Number, must be an integer
# =begin
# (math:bitAnd 4 12) # 4
# (math:bitAnd 4 10) # 0
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let bitAnd (fun (_a _b) (builtin__math:bitAnd _a _b)))

# @brief Bitwise or
# @param lhs Number, must be an integer
# @param rhs Number, must be an integer
# =begin
# (math:bitOr 4 10) # 14
# (math:bitOr 4 1) # 5
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let bitOr (fun (_a _b) (builtin__math:bitOr _a _b)))

# @brief Bitwise exclusive or of lhs and rhs
# @param lhs Number, must be an integer
# @param rhs Number, must be an integer
# =begin
# (math:bitXor 4 12) # 8
# (math:bitXor 4 10) # 14
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let bitXor (fun (_a _b) (builtin__math:bitXor _a _b)))

# @brief Left bit shift
# @param lhs Number, must be an integer
# @param rhs Number, must be an integer
# =begin
# (math:lshift 3 2) # 12
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let lshift (fun (_a _b) (builtin__math:lshift _a _b)))

# @brief Right bit shift
# @param lhs Number, must be an integer
# @param rhs Number, must be an integer
# =begin
# (math:rshift 13 2) # 3
# (math:rshift -14 2) # -4
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let rshift (fun (_a _b) (builtin__math:rshift _a _b)))

# @brief Finds the smallest integral power of 2 not less than the given value
# @param value Number, must be an integer
# =begin
# (math:bitCeil 4) # 4
# (math:bitCeil 7) # 8
# (math:bitCeil 8) # 8
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let bitCeil (fun (_x) (builtin__math:bitCeil _x)))

# @brief Finds the largest integral power of 2 not greater than the given value
# @param value Number, must be an integer
# =begin
# (math:bitFloor 4) # 4
# (math:bitFloor 7) # 4
# (math:bitFloor 8) # 8
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let bitFloor (fun (_x) (builtin__math:bitFloor _x)))

# @brief Finds the smallest number of bits needed to represent the given value
# @param value Number, must be an integer
# =begin
# (math:bitWidth 2) # 2
# (math:bitWidth 7) # 3
# (math:bitWidth 8) # 4
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let bitWidth (fun (_x) (builtin__math:bitWidth _x)))

# @brief Counts the number of consecutive 0 bits, starting from the most significant bit
# @param n Number, must be an integer
# @param bits Number of bits to represent n in, must be an integer
# =begin
# (math:countLeftZeros 30 8) # 3
# (math:countLeftZeros 227 8) # 0
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let countLeftZeros (fun (_n _bits) (builtin__math:countLeftZeros _n _bits)))

# @brief Counts the number of consecutive 1 bits, starting from the most significant bit
# @param n Number, must be an integer
# @param bits Number of bits to represent n in, must be an integer
# =begin
# (math:countLeftOnes 30 8) # 4
# (math:countLeftOnes 227 8) # 3
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let countLeftOnes (fun (_n _bits) (builtin__math:countLeftOnes _n _bits)))

# @brief Counts the number of consecutive 0 bits, starting from the least significant bit
# @param n Number, must be an integer
# @param bits Number of bits to represent n in, must be an integer
# =begin
# (math:countRightZeros 30 8) # 1
# (math:countRightZeros 227 8) # 0
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let countRightZeros (fun (_n _bits) (builtin__math:countRightZeros _n _bits)))

# @brief Counts the number of consecutive 1 bits, starting from the least significant bit
# @param n Number, must be an integer
# @param bits Number of bits to represent n in, must be an integer
# =begin
# (math:countRightOnes 30 8) # 0
# (math:countRightOnes 227 8) # 2
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let countRightOnes (fun (_n _bits) (builtin__math:countRightOnes _n _bits)))

# @brief Computes the result of bitwise left-rotation of _x by _count
# @param _x Number, must be an integer
# @param _count Number, must be an integer
# @param _bytecount Number of bytes to shift on, must be an integer
# =begin
# (math:circularLeftShift 29 4 1) # 209
# (math:circularLeftShift 29 9 1) # 58
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let circularLeftShift (fun (_x (mut _count) _bytecount) {
(assert (and (>= _bytecount 1) (<= _bytecount 8)) "bytecount must be in [1, 8]")
(let _max (- (* 8 _bytecount) 1))
(let _mask (- (lshift 1 (* 8 _bytecount)) 1))
(set _count (bitAnd _count _max))
(bitAnd (bitOr (lshift _x _count) (rshift _x (bitAnd (* -1 _count) _max))) _mask) }))

# @brief Computes the result of bitwise left-rotation of _x by _count
# @param _x Number, must be an integer
# @param _count Number, must be an integer
# @param _bytecount Number of bytes to shift on, must be an integer
# =begin
# (math:circularRightShift 29 9 1) # 142
# (math:circularRightShift 29 2 1) # 71
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let circularRightShift (fun (_x (mut _count) _bytecount) {
(assert (and (>= _bytecount 1) (<= _bytecount 8)) "bytecount must be in [1, 8]")
(let _max (- (* 8 _bytecount) 1))
(let _mask (- (lshift 1 (* 8 _bytecount)) 1))
(set _count (bitAnd _count _max))
(bitAnd (bitOr (rshift _x _count) (lshift _x (bitAnd (* -1 _count) _max))) _mask) }))

(let _base_conversion_alphabet "0123456789abcdefghijklmnopqrstuvwxyz")

# @brief Convert a number in a another base (in [2, 36[)
# @param _x Number, must be an integer
# @param _base Number, must be an integer
# =begin
# (math:toBase 10 2) # "1010"
# (math:toBase 165 16) # "a5"
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let toBase (fun ((mut _x) _base) {
(assert (and (> _base 1) (< _base 36)) "Base must be in [2, 36[")
(mut _out "")
(while _x {
(set _out (+ (@ _base_conversion_alphabet (mod _x _base)) _out))
(set _x (floordiv _x _base)) })
_out }))

# @brief Count the digits of a number in a given base (in [2, 36[)
# @param _x Number, must be an integer
# @param _base Number, must be an integer
# =begin
# (math:countDigits 10 2) # 4
# (math:countDigits 165 16) # 2
# =end
# @author https://github.com/SuperFola
# @require 4.6.0 Requires ArkScript 4.6.0 or later
(let countDigits (fun ((mut _x) _base) {
(assert (and (> _base 1) (< _base 36)) "Base must be in [2, 36[")
(mut _out 0)
(while _x {
(set _out (+ 1 _out))
(set _x (floordiv _x _base)) })
_out }))

# @brief Return the absolute value of a number
# @param _x the number to get the absolute value of
# @author https://github.com/rstefanic
Expand Down Expand Up @@ -214,7 +442,23 @@
# @param _x the number to pow
# @param _a the exponent
# @author https://github.com/SuperFola
(let pow (fun (_x _a) (exp (* _a (ln _x)))))
(let pow (fun ((mut _x) (mut _a)) {
(if (= 0 (mod _a 1))
(if (= 1 _a)
_x
(if (= 0 _a)
1
{
(let _c _x)
(if (> _a 0)
(while (> _a 1) {
(set _x (* _c _x))
(set _a (- _a 1)) })
(while (<= _a 0) {
(set _x (/ _x _c))
(set _a (+ _a 1)) }))
_x }))
(exp (* _a (ln _x)))) }))

# @brief Get the square root of a number
# @details Square roots can't be taken for negative numbers for obvious reasons.
Expand Down
4 changes: 3 additions & 1 deletion Testing.ark
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@
(set testing:_suite (testing:_make_suite ($repr _name)))

(let ($symcat _name "-output") (testing:_runner
($repr _name)
($if (= "String" ($type _name))
_name
($repr _name))
(fun () ($as-is
{
_body }))))
Expand Down
62 changes: 61 additions & 1 deletion tests/math-tests.ark
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,65 @@
(test:eq (builtin__math:tanh 5) (math:tanh 5))
(test:eq (builtin__math:acosh 5) (math:acosh 5))
(test:eq (builtin__math:asinh 5) (math:asinh 5))
(test:eq (builtin__math:atanh 0.5) (math:atanh 0.5)) })
(test:eq (builtin__math:atanh 0.5) (math:atanh 0.5))
(test:eq (builtin__math:countOnes 1234) (math:countOnes 1234))
(test:eq (builtin__math:countZeros 1234) (math:countZeros 1234))
(test:eq (builtin__math:bitNot 1234) (math:bitNot 1234))
(test:eq (builtin__math:bitAnd 1234 5678) (math:bitAnd 1234 5678))
(test:eq (builtin__math:bitOr 1234 5678) (math:bitOr 1234 5678))
(test:eq (builtin__math:bitXor 1234 5678) (math:bitXor 1234 5678))
(test:eq (builtin__math:lshift 1234 2) (math:lshift 1234 2))
(test:eq (builtin__math:rshift 1234 6) (math:rshift 1234 6))
(test:eq (builtin__math:bitCeil 1234) (math:bitCeil 1234))
(test:eq (builtin__math:bitFloor 1234) (math:bitFloor 1234))
(test:eq (builtin__math:bitWidth 1234) (math:bitWidth 1234))
(test:eq (builtin__math:countLeftZeros 1234 32) (math:countLeftZeros 1234 32))
(test:eq (builtin__math:countLeftOnes 1234 32) (math:countLeftOnes 1234 32))
(test:eq (builtin__math:countRightZeros 1234 32) (math:countRightZeros 1234 32))
(test:eq (builtin__math:countRightOnes 1234 32) (math:countRightOnes 1234 32)) })

(test:case "bitwise" {
(test:eq (math:countOnes 5) 2)
(test:eq (math:countOnes 63) 6)
(test:eq (math:countZeros 63) 58)
(test:eq (math:countZeros 65535) 48)

(test:eq (math:bitNot 5) -6)
(test:eq (math:bitAnd 4 12) 4)
(test:eq (math:bitAnd 4 10) 0)
(test:eq (math:bitOr 4 10) 14)
(test:eq (math:bitOr 4 1) 5)
(test:eq (math:bitXor 4 12) 8)
(test:eq (math:bitXor 4 10) 14)
(test:eq (math:lshift 3 2) 12)
(test:eq (math:rshift 13 2) 3)
(test:eq (math:rshift -14 2) -4)

(test:eq (math:countLeftZeros 30 8) 3)
(test:eq (math:countLeftZeros 227 8) 0)
(test:eq (math:countLeftOnes 30 5) 4)
(test:eq (math:countLeftOnes 30 8) 0)
(test:eq (math:countLeftOnes 227 8) 3)
(test:eq (math:countRightZeros 30 8) 1)
(test:eq (math:countRightZeros 227 8) 0)
(test:eq (math:countRightOnes 30 8) 0)
(test:eq (math:countRightOnes 227 8) 2)

(test:eq (math:circularLeftShift 29 4 1) 209)
(test:eq (math:circularLeftShift 29 9 1) 58)
(test:eq (math:circularRightShift 29 9 1) 142)
(test:eq (math:circularRightShift 29 2 1) 71) })

(test:case "toBase" {
(test:eq (math:toBase 10 10) "10")
(test:eq (math:toBase 10 16) "a")
(test:eq (math:toBase 10 2) "1010")
(test:eq (math:toBase 165 16) "a5") })

(test:case "countDigits" {
(test:eq (math:countDigits 10 2) 4)
(test:eq (math:countDigits 10 10) 2)
(test:eq (math:countDigits 165 16) 2) })

(test:case "abs" {
(test:eq (math:abs -1) 1)
Expand Down Expand Up @@ -80,6 +138,8 @@

(test:case "pow" {
(test:eq (math:pow 2 2) 4)
(test:eq (math:pow 2 3) 8)
(test:eq (math:pow 2 -3) 0.125)
(test:eq (math:pow 4 0.5) 2) })

(test:case "clamp" {
Expand Down
2 changes: 1 addition & 1 deletion tests/string-tests.ark
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
(test:eq (string:toUpper "ABCDEFGHIJKLMNOPQRSTUVWXYZ") "ABCDEFGHIJKLMNOPQRSTUVWXYZ") })

(test:case "reverse" {
(test:eq (string:reverse "dlrow olleh") "hello world" )
(test:eq (string:reverse "dlrow olleh") "hello world")
(test:eq (string:reverse "") "")
(test:eq (string:reverse "a") "a") })

Expand Down
2 changes: 1 addition & 1 deletion tests/switch-tests.ark
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
(test:expect true))
called }))

(test:suite switch {
(test:suite "switch" {
(switch 12
0 (test:expect false)
-1 (test:expect false)
Expand Down
Loading