diff --git a/Cargo.toml b/Cargo.toml
index 6a1886f..1ac735b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,3 +6,5 @@ edition = "2024"
 [dependencies]
 rand = "0.9.0"
 paste = "1.0.15"
+rust_decimal = "1.37"
+rust_decimal_macros = "1.37"
diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs
index be92ad7..fac2c62 100644
--- a/src/instructions/mod.rs
+++ b/src/instructions/mod.rs
@@ -1,24 +1,40 @@
 #[macro_use]
 pub mod macros {
-    //  A macro that makes a push instruction given: the name of the stack to use,
-    //  an internal function to call, and the type of a function.
+    /// A macro that makes a push instruction given: the name of the input stack to use,
+    /// the name of the output stack, an internal function to call, the type of a function,
+    /// and the arity of the internal function call.
+    ///
+    /// The `in_stack` argument refers to which push stack should this operate on.
+    /// The `out_stack` argument refers to which push stack should the result be pushed to.
+    /// The `fn_name` argement refers to the name of the function that is to operate
+    /// on the values popped from `in_stack`.
+    /// The `fn_type` argument refers to the type of `in_stack`. For example, the
+    /// int stack is type: *Vec<i128>*. `fn_type` is *i128* in this case.
+    /// The `fn_arity` argument refers to how many popped stack items are needed to
+    /// execute the instruction. If the amount of items in the stack is less than
+    /// this value, the instruction does nothing.
+    ///
+    /// What causes an instruction to NoOp:
+    /// 1) There aren't enough values on a stack to execute an instruction.
+    /// 2) The internal operation the instruction executes is unable to be ran without
+    ///    erroring such as division by 0.
     #[macro_export]
     macro_rules! make_instruction {
-        ($stack_name:ident, $fn_name:ident, $fn_type:ty) => {
+        ($in_stack:ident, $out_stack:ident, $fn_name:ident, $fn_type:ty, $fn_arity:stmt) => {
             paste::item! {
-                fn [< $stack_name $fn_name >] (state: &mut PushState, num_inputs: usize) {
-                    if state.$stack_name.len() < num_inputs {
+                fn [< $in_stack $fn_name >] (state: &mut PushState) {
+                    if state.$in_stack.len() < $fn_arity {
                         return;
                     }
-                    let mut inputs: Vec<$fn_type> = Vec::with_capacity(num_inputs);
-                    for n in 0..num_inputs {
-                        inputs.push(state.$stack_name[n]);
+                    let mut inputs: Vec<$fn_type> = Vec::with_capacity($fn_arity);
+                    for n in 1..=$fn_arity {
+                        inputs.push(state.$in_stack[state.$in_stack.len() - n]);
                     }
                     if let Some(result) = $fn_name(inputs) {
-                        for _ in 0..num_inputs {
-                            state.$stack_name.pop();
+                        for _ in 0..$fn_arity {
+                            state.$in_stack.pop();
                         }
-                        state.$stack_name.push(result);
+                        state.$out_stack.push(result);
                     }
                 }
             }
diff --git a/src/instructions/numeric.rs b/src/instructions/numeric.rs
index b1cad92..924e121 100644
--- a/src/instructions/numeric.rs
+++ b/src/instructions/numeric.rs
@@ -3,32 +3,82 @@
 //! This file contains numeric instructions for int and float.
 
 use crate::push::state::{EMPTY_STATE, PushState};
-use std::ops::{Add, Sub};
+use rust_decimal::Decimal;
+use std::cmp::{max, min};
+use std::ops::{Add, Div, Mul, Sub};
+
+use super::utils::CheckedDiv;
 
 /// Adds two addable values together.
 fn _add<T>(vals: Vec<T>) -> Option<T>
 where
-    T: Add<Output = T>,
-    T: Copy,
+    T: Add<Output = T> + Copy,
 {
     Some(vals[1] + vals[0])
 }
+make_instruction!(int, int, _add, i128, 2);
+make_instruction!(float, float, _add, Decimal, 2);
 
 /// Subtracts two subtractable values from each other.
 fn _sub<T>(vals: Vec<T>) -> Option<T>
 where
-    T: Sub<Output = T>,
-    T: Copy,
+    T: Sub<Output = T> + Copy,
 {
     Some(vals[1] - vals[0])
 }
+make_instruction!(int, int, _sub, i128, 2);
+make_instruction!(float, float, _sub, Decimal, 2);
 
-/// Declares int_add
-make_instruction!(int, _add, i64);
+/// Multiplies two multipliable values together.
+fn _mult<T>(vals: Vec<T>) -> Option<T>
+where
+    T: Mul<Output = T> + Copy,
+{
+    Some(vals[1] * vals[0])
+}
+make_instruction!(int, int, _mult, i128, 2);
+make_instruction!(float, float, _mult, Decimal, 2);
+
+/// Divides two values from each other.
+fn _div<T>(vals: Vec<T>) -> Option<T>
+where
+    T: Div<Output = T> + Copy + CheckedDiv,
+{
+    vals[1].checked_div(vals[0])
+}
+make_instruction!(int, int, _div, i128, 2);
+make_instruction!(float, float, _div, Decimal, 2);
+
+/// Takes the remainder of two values
+fn _rem<T>(vals: Vec<T>) -> Option<T>
+where
+    T: Div<Output = T> + Copy + CheckedDiv,
+{
+    vals[1].checked_mod(vals[0])
+}
+make_instruction!(int, int, _rem, i128, 2);
+make_instruction!(float, float, _rem, Decimal, 2);
+
+/// Takes the max of two values
+fn _max<T>(vals: Vec<T>) -> Option<T>
+where
+    T: Ord + Copy,
+{
+    Some(max(vals[1], vals[0]))
+}
+
+/// Takes the min of two values
+fn _min<T>(vals: Vec<T>) -> Option<T>
+where
+    T: Ord + Copy,
+{
+    Some(min(vals[1], vals[0]))
+}
 
 #[cfg(test)]
 mod tests {
     use super::*;
+    use rust_decimal_macros::dec;
 
     /// Tests the _add function.
     #[test]
@@ -36,8 +86,8 @@ mod tests {
         let vals: Vec<i64> = vec![1, 2];
         assert_eq!(Some(3), _add(vals));
 
-        let vals: Vec<f64> = vec![1.1, 2.2];
-        assert_eq!(Some(3.3), _add(vals));
+        let vals: Vec<Decimal> = vec![dec!(1.1), dec!(2.2)];
+        assert_eq!(Some(dec!(3.3)), _add(vals));
     }
 
     /// Tests the _sub function.
@@ -46,17 +96,170 @@ mod tests {
         let vals: Vec<i64> = vec![1, 2];
         assert_eq!(Some(1), _sub(vals));
 
-        let vals: Vec<f64> = vec![1.1, 2.2];
-        assert_eq!(Some(1.1), _sub(vals));
+        let vals: Vec<Decimal> = vec![dec!(1.1), dec!(2.2)];
+        assert_eq!(Some(dec!(1.1)), _sub(vals));
     }
 
-    // Tests that the various state_add functions work.
+    /// Tests the _mult function.
+    #[test]
+    fn mult_test() {
+        let vals: Vec<i128> = vec![4, 5];
+        assert_eq!(Some(20), _mult(vals));
+
+        let vals: Vec<Decimal> = vec![dec!(1.1), dec!(2.2)];
+        assert_eq!(Some(dec!(2.42)), _mult(vals));
+    }
+
+    /// Tests the _div function
+    #[test]
+    fn div_test() {
+        let vals: Vec<i128> = vec![4, 20];
+        assert_eq!(Some(5), _div(vals));
+
+        let vals: Vec<i128> = vec![3, 20];
+        assert_eq!(Some(6), _div(vals));
+
+        let vals: Vec<Decimal> = vec![dec!(1.6), dec!(2.2)];
+        assert_eq!(Some(dec!(1.375)), _div(vals));
+
+        let vals: Vec<i128> = vec![0, 1];
+        assert_eq!(None, _div(vals));
+    }
+
+    /// Tests the _rem function
+    #[test]
+    fn rem_test() {
+        let vals: Vec<i128> = vec![3, 20];
+        assert_eq!(Some(2), _rem(vals));
+
+        let vals: Vec<i128> = vec![20, 20];
+        assert_eq!(Some(0), _rem(vals));
+
+        let vals: Vec<i128> = vec![0, 9];
+        assert_eq!(None, _rem(vals));
+    }
+
+    /// Tests the _max function
+    #[test]
+    fn max_test() {
+        let vals: Vec<i128> = vec![1, 2];
+        assert_eq!(Some(2), _max(vals));
+
+        let vals: Vec<i128> = vec![3, 0];
+        assert_eq!(Some(3), _max(vals));
+
+        let vals: Vec<Decimal> = vec![dec!(2.2), dec!(1.1)];
+        assert_eq!(Some(dec!(2.2)), _max(vals));
+
+        let vals: Vec<Decimal> = vec![dec!(3.3), dec!(-1.1)];
+        assert_eq!(Some(dec!(3.3)), _max(vals));
+    }
+
+    /// Tests the _min function
+    #[test]
+    fn min_test() {
+        let vals: Vec<i128> = vec![1, 2];
+        assert_eq!(Some(1), _min(vals));
+
+        let vals: Vec<i128> = vec![3, 0];
+        assert_eq!(Some(0), _min(vals));
+
+        let vals: Vec<Decimal> = vec![dec!(2.2), dec!(1.1)];
+        assert_eq!(Some(dec!(1.1)), _min(vals));
+
+        let vals: Vec<Decimal> = vec![dec!(3.3), dec!(-1.1)];
+        assert_eq!(Some(dec!(-1.1)), _min(vals));
+    }
+
+    /// Tests that the various addition functions.
     #[test]
     fn state_add() {
         let mut test_state = EMPTY_STATE;
         test_state.int = vec![1, 2];
-        test_state.float = vec![1.1, 2.2];
-        int_add(&mut test_state, 2);
-        assert_eq!(test_state.int, vec![3]);
+        test_state.float = vec![dec!(1.1), dec!(2.2)];
+
+        int_add(&mut test_state);
+        assert_eq!(vec![3], test_state.int);
+
+        float_add(&mut test_state);
+        assert_eq!(vec![dec!(3.3)], test_state.float);
+    }
+
+    /// Tests the various subtraction functions.
+    #[test]
+    fn state_sub() {
+        let mut test_state = EMPTY_STATE;
+        test_state.int = vec![1, 2];
+        test_state.float = vec![dec!(1.1), dec!(2.2)];
+
+        int_sub(&mut test_state);
+        assert_eq!(vec![-1], test_state.int);
+
+        float_sub(&mut test_state);
+        assert_eq!(vec![dec!(-1.1)], test_state.float);
+    }
+
+    /// Tests the various multiplication functions.
+    #[test]
+    fn state_mult() {
+        let mut test_state = EMPTY_STATE;
+
+        test_state.int = vec![0];
+        int_mult(&mut test_state);
+        assert_eq!(vec![0], test_state.int);
+
+        test_state.int = vec![10, 3, 2];
+        test_state.float = vec![dec!(1.1), dec!(2.2)];
+
+        int_mult(&mut test_state);
+        assert_eq!(vec![10, 6], test_state.int);
+
+        float_mult(&mut test_state);
+        assert_eq!(vec![dec!(2.42)], test_state.float);
+    }
+
+    /// Tests the division functions in the state
+    #[test]
+    fn state_div() {
+        let mut test_state = EMPTY_STATE;
+
+        test_state.int = vec![0];
+        int_div(&mut test_state);
+        assert_eq!(vec![0], test_state.int);
+
+        test_state.int = vec![2, 0];
+        int_div(&mut test_state);
+        assert_eq!(vec![2, 0], test_state.int);
+
+        test_state.int = vec![6, 3];
+
+        int_div(&mut test_state);
+        assert_eq!(vec![2], test_state.int);
+
+        test_state.float = vec![dec!(2.2), dec!(1.6)];
+        float_div(&mut test_state);
+        assert_eq!(vec![dec!(1.375)], test_state.float);
+    }
+
+    /// Tests the remainder functions in the state.
+    #[test]
+    fn state_rem() {
+        let mut test_state = EMPTY_STATE;
+
+        test_state.int = vec![0];
+        int_rem(&mut test_state);
+        assert_eq!(vec![0], test_state.int);
+
+        test_state.int = vec![2, 0];
+        int_rem(&mut test_state);
+        assert_eq!(vec![2, 0], test_state.int);
+
+        test_state.int = vec![60, 80, 20, 3];
+        int_rem(&mut test_state);
+        assert_eq!(vec![60, 80, 2], test_state.int);
+
+        test_state.float = vec![dec!(2.7), dec!(1.2)];
+        float_rem(&mut test_state);
+        assert_eq!(vec![dec!(0.3)], test_state.float);
     }
 }
diff --git a/src/instructions/utils.rs b/src/instructions/utils.rs
index 8b13789..8596275 100644
--- a/src/instructions/utils.rs
+++ b/src/instructions/utils.rs
@@ -1 +1,26 @@
+use rust_decimal::Decimal;
+use rust_decimal_macros::dec;
+use std::ops::Div;
 
+pub trait CheckedDiv: Sized + Div<Output = Self> {
+    fn checked_div(self, v: Self) -> Option<Self>;
+    fn checked_mod(self, v: Self) -> Option<Self>;
+}
+
+impl CheckedDiv for Decimal {
+    fn checked_div(self, v: Self) -> Option<Self> {
+        if v == dec!(0.0) { None } else { Some(self / v) }
+    }
+    fn checked_mod(self, v: Self) -> Option<Self> {
+        if v == dec!(0.0) { None } else { Some(self % v) }
+    }
+}
+
+impl CheckedDiv for i128 {
+    fn checked_div(self, v: Self) -> Option<Self> {
+        if v == 0 { None } else { Some(self / v) }
+    }
+    fn checked_mod(self, v: Self) -> Option<Self> {
+        if v == 0 { None } else { Some(self % v) }
+    }
+}
diff --git a/src/main.rs b/src/main.rs
index 031ce84..26c103c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,18 @@
+use rust_decimal::prelude::*;
+use rust_decimal_macros::dec;
+
 mod instructions;
 mod push;
 
 fn main() {
-    let arr: Vec<i32> = vec![];
-    let slice = &arr[..2];
-    println!("{:?}", slice);
+    // let arr: Vec<i32> = vec![];
+    // let slice = &arr[..2];
+    // println!("{:?}", slice);
+
+    // let arr: Vec<Decimal> = vec![dec!(2.2), dec!(1.1)];
+    // println!("{arr:?}");
+
+    // let result = dec!(1.0) / dec!(0.0);
+    let result = dec!(2.7) % dec!(1.2);
+    println!("{result}");
 }
diff --git a/src/push/state.rs b/src/push/state.rs
index aea2c74..c4aee36 100644
--- a/src/push/state.rs
+++ b/src/push/state.rs
@@ -1,12 +1,18 @@
+use rust_decimal::prelude::*;
+
+/// The declaration of the state that push operates on.
+///
+/// I chose to use `rust_decimal` crate here because
+/// there are round off errors with the build in `f64`.
 #[derive(Debug, Clone)]
 pub struct PushState {
-    pub int: Vec<i64>,
-    pub float: Vec<f64>,
+    pub int: Vec<i128>,
+    pub float: Vec<Decimal>,
     pub string: Vec<Vec<u8>>,
     pub bool: Vec<bool>,
     pub char: Vec<u8>,
-    pub vector_int: Vec<Vec<i64>>,
-    pub vector_float: Vec<Vec<f64>>,
+    pub vector_int: Vec<Vec<i128>>,
+    pub vector_float: Vec<Vec<Decimal>>,
     pub vector_string: Vec<Vec<Vec<u8>>>,
     pub vector_bool: Vec<Vec<bool>>,
     pub vector_char: Vec<u8>,