How to convert a Hex string to a Decimal number in Clojure
The best way to learn any new programming language is to practice.
This applies especially to such a beautiful functional-programming language like Clojure with thousands of functions.
Today I created my own super basic “Hex to Decimal Converter”, and it’s definitely not the most elegant nor performant way to do it in Clojure. Normally you would probably do some bitshifting, utilizing Java functions and string formatting.
But it works and I learned about a new function called map-indexed, which came handy in the for - list comprehension as the use of an atom was an overkill for the trivial need of an incrementing index counter.
Decimal vs Hexadecimal
Decimal is base 10 and uses 10 distinct characters to count.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Hexadecimal is base 16 and uses 16 distinct characters to count.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, plus the letters A, B, C, D, E, F.
Decimal to Hexadecimal Conversion Table
Decimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Hexadecimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
How to convert from Hex to Decimal
Let’s take the hex number AF7B5 . It is made up of A, F, 7, B, 5.
We start from right with 5 and go backwards.
5 x (16^0) = 5 x (1) = 5 x 1 = 5
B x (16^1) = 11 x (16) = 11 x 16 = 176
7 x (16^2) = 7 x (16 x 16) = 7 x 256 = 1792
F x (16^3) = 15 x (16 x 16 x 16) = 15 x 4096 = 61440
A x (16^4) = 10 x (16 x 16 x 16 x 16) = 10 x 65536 = 655360
============================================================
Total 718773
Summarize the results
5 + 176 + 1792 + 61440 + 655360 = 718773
So the decimal equivalent of AF7B5 is 718773.
Clojure Algorithm
(def hex-value {:0 0
:1 1
:2 2
:3 3
:4 4
:5 5
:6 6
:7 7
:8 8
:9 9
:a 10
:b 11
:c 12
:d 13
:e 14
:f 15})
(defn hex-to-reverse-keyword-vector
"Convert a hex string to a reverse keyword vector"
[hex]
(->> (str/lower-case hex)
reverse
(map str)
(map keyword)
vec))
;; user=> (hex-to-reverse-keyword-vector "ABCDEF")
;; [:f :e :d :c :b :a]
;; user=> (map-indexed vector (hex-to-reverse-keyword-vector "ABCDEF"))
;; ([0 :f] [1 :e] [2 :d] [3 :c] [4 :b] [5 :a])
(defn hex-to-decimal
"Calculate the decimal value of a given hex-string"
[hex]
(->> (for [x (map-indexed vector (hex-to-reverse-keyword-vector hex))]
(->> (* ((second x) hex-value)
(Math/pow 16 (first x)))))
(reduce +)))
;; user=> (hex-to-decimal "5B3E")
;; 23358.0