diff --git a/code/libs/s_html/hexadecimal.dm b/code/libs/s_html/hexadecimal.dm
index fcd7b57d453..b6779bc8600 100644
--- a/code/libs/s_html/hexadecimal.dm
+++ b/code/libs/s_html/hexadecimal.dm
@@ -53,45 +53,32 @@ proc/hex2num(hex)
return(num)
-
-proc/num2hex(num, placeholder=2)
- //Converts a numeral (eg. 255) into a hexadecimal string (eg. "FF")
- //The 'placeholder' argument inserts zeroes in front of the string
- // until the string is that length -- eg. 15 in hexadecimal is "F",
- // but the placeholder of 2 would make it "0F".
-
+//Returns the hex value of a decimal number
+//len == length of returned string
+//if len < 0 then the returned string will be as long as it needs to be to contain the data
+//Only supports positive numbers
+//if an invalid number is provided, it assumes num==0
+/proc/num2hex(var/num, var/len = 2)
if(!isnum(num))
- CRASH("num2hex not given a numeric argument (user error)")
- return
-
- if(!num)
- return("0") //no computation necessary
-
- var/hex = ""
-
- var/i = 0
- while(16**i < num) i++
-
- for(var/power = i-1, power >= 0, power--)
- var/val = round( num / (16 ** power) )
- num -= val * (16 ** power)
- switch(val)
- if(0,1,2,3,4,5,6,7,8,9)
- hex += "[val]"
-
- if(10)
- hex += "A"
- if(11)
- hex += "B"
- if(12)
- hex += "C"
- if(13)
- hex += "D"
- if(14)
- hex += "E"
- if(15)
- hex += "F"
-
- while(lentext(hex) < placeholder) hex = "0[hex]"
-
- return(hex)
\ No newline at end of file
+ num = 0
+ num = round(abs(num))
+ . = ""
+ var/i=0
+ while(1)
+ if(len<=0)
+ if(!num)
+ break
+ else
+ if(i>=len)
+ break
+ var/remainder = num/16
+ num = round(remainder)
+ remainder = (remainder - num) * 16
+ switch(remainder)
+ if(1 to 9)
+ . = "[remainder]" + .
+ if(10 to 15)
+ . = ascii2text(remainder+55) + .
+ else
+ . = "0" + .
+ i++
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index ddff2225804..b15db50535b 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -2,5 +2,6 @@
#include "unit_test.dm"
#include "circuitboards.dm"
#include "dna_and_disabilities.dm"
+#include "hexadecimal.dm"
#include "reagent_recipe_collisions.dm"
#endif
diff --git a/code/modules/unit_tests/hexadecimal.dm b/code/modules/unit_tests/hexadecimal.dm
new file mode 100644
index 00000000000..b76ba8470c5
--- /dev/null
+++ b/code/modules/unit_tests/hexadecimal.dm
@@ -0,0 +1,21 @@
+/datum/unit_test/num2hex/start()
+ assert_eq(num2hex(0, 1), "0")
+ assert_eq(num2hex(1, 1), "1")
+ assert_eq(num2hex(15, 1), "F")
+ assert_eq(num2hex(16, 1), "0")
+ assert_eq(num2hex(0xABCDE, 1), "E")
+ assert_eq(num2hex(SHORT_REAL_LIMIT-1, 1), "F")
+
+ assert_eq(num2hex(0, 2), "00")
+ assert_eq(num2hex(1, 2), "01")
+ assert_eq(num2hex(15, 2), "0F")
+ assert_eq(num2hex(16, 2), "10")
+ assert_eq(num2hex(0xABCDE, 2), "DE")
+ assert_eq(num2hex(SHORT_REAL_LIMIT-1, 2), "FF")
+
+ assert_eq(num2hex(0, 8), "00000000")
+ assert_eq(num2hex(1, 8), "00000001")
+ assert_eq(num2hex(15, 8), "0000000F")
+ assert_eq(num2hex(16, 8), "00000010")
+ assert_eq(num2hex(0xABCDE, 8), "000ABCDE")
+ assert_eq(num2hex(SHORT_REAL_LIMIT-1, 8), "00FFFFFF")
diff --git a/code/modules/unit_tests/unit_test.dm b/code/modules/unit_tests/unit_test.dm
index b3539c68839..ffe43d8ee33 100644
--- a/code/modules/unit_tests/unit_test.dm
+++ b/code/modules/unit_tests/unit_test.dm
@@ -70,3 +70,5 @@ var/failed_any_test = FALSE
CHECK_TICK
del(world)
+
+#define assert_eq(a, b) (a == b || (fail("[__FILE__]:[__LINE__]: assert_eq failed. Expected [b], got [a].")))