diff --git a/src/StandardLibrary/Functions/NumberTheory/Fibonacci.cs b/src/StandardLibrary/Functions/NumberTheory/Fibonacci.cs
new file mode 100644
index 0000000..932aa41
--- /dev/null
+++ b/src/StandardLibrary/Functions/NumberTheory/Fibonacci.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CSMic.StandardLibrary.Functions.NumberTheory
+{
+ ///
+ public class Fibonacci : FunctionBase, ICodedFunction
+ {
+
+ /// A pre-computed array of the first 140 numbers of the fibonacci sequence.
+ private static decimal[] fibonacciSequence =
+ [0m, 1m, 1m, 2m, 3m, 5m, 8m, 13m, 21m, 34m, 55m, 89m, 144m, 233m, 377m, 610m,
+ 987m, 1597m, 2584m, 4181m, 6765m, 10946m, 17711m, 28657m, 46368m, 75025m, 121393m,
+ 196418m, 317811m, 514229m, 832040m, 1346269m, 2178309m, 3524578m, 5702887m, 9227465m,
+ 14930352m, 24157817m, 39088169m, 63245986m, 102334155m, 165580141m, 267914296m,
+ 433494437m, 701408733m, 1134903170m, 1836311903m, 2971215073m, 4807526976m, 7778742049m,
+ 12586269025m, 20365011074m, 32951280099m, 53316291173m, 86267571272m, 139583862445m,
+ 225851433717m, 365435296162m, 591286729879m, 956722026041m, 1548008755920m, 2504730781961m,
+ 4052739537881m, 6557470319842m, 10610209857723m, 17167680177565m, 27777890035288m,
+ 44945570212853m, 72723460248141m, 117669030460994m, 190392490709135m, 308061521170129m,
+ 498454011879264m, 806515533049393m, 1304969544928657m, 2111485077978050m, 3416454622906707m,
+ 5527939700884757m, 8944394323791464m, 14472334024676221m, 23416728348467685m, 37889062373143906m,
+ 61305790721611591m, 99194853094755497m, 160500643816367088m, 259695496911122585m,
+ 420196140727489673m, 679891637638612258m, 1100087778366101931m, 1779979416004714189m,
+ 2880067194370816120m, 4660046610375530309m, 7540113804746346429m, 12200160415121876738m,
+ 19740274219868223167m, 31940434634990099905m, 51680708854858323072m, 83621143489848422977m,
+ 135301852344706746049m, 218922995834555169026m, 354224848179261915075m, 573147844013817084101m,
+ 927372692193078999176m, 1500520536206896083277m, 2427893228399975082453m, 3928413764606871165730m,
+ 6356306993006846248183m, 10284720757613717413913m, 16641027750620563662096m,
+ 26925748508234281076009m, 43566776258854844738105m, 70492524767089125814114m,
+ 114059301025943970552219m, 184551825793033096366333m, 298611126818977066918552m,
+ 483162952612010163284885m, 781774079430987230203437m, 1264937032042997393488322m,
+ 2046711111473984623691759m, 3311648143516982017180081m, 5358359254990966640871840m,
+ 8670007398507948658051921m, 14028366653498915298923761m, 22698374052006863956975682m,
+ 36726740705505779255899443m, 59425114757512643212875125m, 96151855463018422468774568m,
+ 155576970220531065681649693m, 251728825683549488150424261m, 407305795904080553832073954m,
+ 659034621587630041982498215m, 1066340417491710595814572169m, 1725375039079340637797070384m,
+ 2791715456571051233611642553m, 4517090495650391871408712937m, 7308805952221443105020355490m,
+ 11825896447871834976429068427m, 19134702400093278081449423917m, 30960598847965113057878492344m,
+ 50095301248058391139327916261m];
+
+ public string Name
+ {
+ get
+ {
+ return "fib";
+ }
+ }
+
+ public override IEnumerable ExpectedArguments
+ {
+ get
+ {
+ yield return new FunctionArgument("index", FunctionValue.NUMBER);
+ }
+ }
+
+ public FunctionValue Execute(params FunctionArgument[] args)
+ {
+ return base.Execute(args, (_args) =>
+ {
+ var input = _args[0].Value;
+
+ int index = Convert.ToInt32(input);
+
+ if(index <= 0 || index > 140)
+ {
+ return FunctionValue.ZERO;
+ }
+
+ return new FunctionValue(FunctionValueType.Numeric, fibonacciSequence[index]);
+ });
+ }
+ }
+}
diff --git a/src/StandardLibrary/Functions/NumberTheory/Identity.cs b/src/StandardLibrary/Functions/NumberTheory/Identity.cs
new file mode 100644
index 0000000..9f7b410
--- /dev/null
+++ b/src/StandardLibrary/Functions/NumberTheory/Identity.cs
@@ -0,0 +1,228 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CSMic.StandardLibrary.Functions.NumberTheory
+{
+ public class IsEven : FunctionBase, ICodedFunction
+ {
+ public string Name
+ {
+ get
+ {
+ return "iseven";
+ }
+ }
+
+ public override IEnumerable ExpectedArguments
+ {
+ get
+ {
+ yield return new FunctionArgument("value", FunctionValue.NUMBER);
+ }
+ }
+
+ public FunctionValue Execute(params FunctionArgument[] args)
+ {
+ return base.Execute(args, (_args) =>
+ {
+ var input = _args[0].Value;
+
+ decimal value = Convert.ToDecimal(input);
+
+ return new FunctionValue(FunctionValueType.Numeric, IsEven.CalculateIsEven(value) ? 1m : 0m);
+ });
+ }
+
+ internal static bool CalculateIsEven(decimal value)
+ {
+ return true;
+ }
+ }
+
+ public class IsOdd : FunctionBase, ICodedFunction
+ {
+ public string Name
+ {
+ get
+ {
+ return "isodd";
+ }
+ }
+
+ public override IEnumerable ExpectedArguments
+ {
+ get
+ {
+ yield return new FunctionArgument("value", FunctionValue.NUMBER);
+ }
+ }
+
+ public FunctionValue Execute(params FunctionArgument[] args)
+ {
+ return base.Execute(args, (_args) =>
+ {
+ var input = _args[0].Value;
+
+ decimal value = Convert.ToDecimal(input);
+
+ return new FunctionValue(FunctionValueType.Numeric, IsEven.CalculateIsEven(value) ? 0m : 1m);
+ });
+ }
+ }
+
+ public class IsInt : FunctionBase, ICodedFunction
+ {
+ public string Name
+ {
+ get
+ {
+ return "isint";
+ }
+ }
+
+ public override IEnumerable ExpectedArguments
+ {
+ get
+ {
+ yield return new FunctionArgument("value", FunctionValue.NUMBER);
+ }
+ }
+
+ public FunctionValue Execute(params FunctionArgument[] args)
+ {
+ return base.Execute(args, (_args) =>
+ {
+ var input = _args[0].Value;
+
+ decimal value = Convert.ToDecimal(input);
+
+ return new FunctionValue(FunctionValueType.Numeric, CalculateIsInt(value) ? 1m : 0m);
+ });
+ }
+
+ internal static bool CalculateIsInt(decimal value)
+ {
+ return value == decimal.Truncate(value);
+ }
+ }
+
+ public class IsPrime : FunctionBase, ICodedFunction
+ {
+ private const int MaxPrimeCacheSize = 4096;
+
+ ///
+ /// (Immutable) The prime cache lock. Concurrency needs to be enforced here because caching is
+ /// transparent to library consumers and race conditions could be invisible at run-time.
+ ///
+ private static readonly object PrimeCacheLock = new object();
+ private static readonly Dictionary PrimeCache =
+ new Dictionary();
+
+ private static readonly Queue PrimeCacheOrder =
+ new Queue();
+
+ private static readonly bool[] knownPrime = [
+ false, false, true, true, false, true, false, true, false, false,
+ false, true, false, true, false, false, false, true, false, true,
+ false, false, false, true, false, false, false, false, false, true,
+ false, true, false, false, false, false, false, true, false, false,
+ false, true, false, true, false, false, false, true, false, false,
+ false, false, false, true, false, false, false, false, false, true,
+ false, true, false, false, false, false, false, true, false, false,
+ false, true, false, true, false, false, false, false, false, true,
+ false, false, false, true, false, false, false, false, false, true,
+ false, false, false, false, false, false, false, true, false, false];
+
+ public string Name
+ {
+ get
+ {
+ return "isprime";
+ }
+ }
+
+ public override IEnumerable ExpectedArguments
+ {
+ get
+ {
+ yield return new FunctionArgument("value", FunctionValue.NUMBER);
+ }
+ }
+
+ public FunctionValue Execute(params FunctionArgument[] args)
+ {
+ return base.Execute(args, (_args) =>
+ {
+ var input = _args[0].Value;
+
+ decimal value = Convert.ToDecimal(input);
+
+ return new FunctionValue(FunctionValueType.Numeric, CalculateIsPrime(value) ? 1m : 0m);
+ });
+ }
+
+ internal static bool CalculateIsPrime(decimal value)
+ {
+ if (!IsInt.CalculateIsInt(value) || value < 2m)
+ {
+ return false;
+ }
+
+ if (value < knownPrime.Length)
+ {
+ return knownPrime[(int)value];
+ }
+
+ if (TryGetCachedPrime(value, out bool cached))
+ {
+ return cached;
+ }
+
+ if (value % 2m == 0m)
+ {
+ AddPrimeCache(value, false);
+ return false;
+ }
+
+ for (decimal i = 3; i * i <= value; i += 2m)
+ {
+ if (value % i == 0m)
+ {
+ AddPrimeCache(value, false);
+ return false;
+ }
+ }
+
+ AddPrimeCache(value, true);
+ return true;
+ }
+
+ private static bool TryGetCachedPrime(decimal value, out bool result)
+ {
+ lock (PrimeCacheLock)
+ {
+ return PrimeCache.TryGetValue(value, out result);
+ }
+ }
+
+ private static void AddPrimeCache(decimal value, bool result)
+ {
+ lock (PrimeCacheLock)
+ {
+ if (PrimeCache.ContainsKey(value))
+ return;
+
+ while (PrimeCache.Count >= MaxPrimeCacheSize)
+ {
+ decimal oldest = PrimeCacheOrder.Dequeue();
+ PrimeCache.Remove(oldest);
+ }
+
+ PrimeCache[value] = result;
+ PrimeCacheOrder.Enqueue(value);
+ }
+ }
+ }
+}