Skip to content

Commit 137d820

Browse files
Added main and test files for converting hexadecimal to binary and hexadecimal to decimal (#768)
* Added main and test files for converting hexadecimal to binary and hexadecimal to decimal * Added functionality instead of using predefined function --------- Co-authored-by: Rak Laptudirm <[email protected]>
1 parent 8c8abd9 commit 137d820

File tree

4 files changed

+233
-0
lines changed

4 files changed

+233
-0
lines changed

conversion/hexadecimaltobinary.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
Author: mapcrafter2048
3+
GitHub: https://github.com/mapcrafter2048
4+
*/
5+
6+
// This algorithm will convert any Hexadecimal number(0-9, A-F, a-f) to Binary number(0 or 1).
7+
// https://en.wikipedia.org/wiki/Hexadecimal
8+
// https://en.wikipedia.org/wiki/Binary_number
9+
// Function receives a Hexadecimal Number as string and returns the Binary number as string.
10+
// Supported Hexadecimal number range is 0 to 7FFFFFFFFFFFFFFF.
11+
12+
package conversion
13+
14+
import (
15+
"errors"
16+
"regexp"
17+
"strings"
18+
)
19+
20+
var isValidHex = regexp.MustCompile("^[0-9A-Fa-f]+$").MatchString
21+
22+
// hexToBinary() function that will take Hexadecimal number as string,
23+
// and return its Binary equivalent as a string.
24+
func hexToBinary(hex string) (string, error) {
25+
// Trim any leading or trailing whitespace
26+
hex = strings.TrimSpace(hex)
27+
28+
// Check if the hexadecimal string is empty
29+
if hex == "" {
30+
return "", errors.New("input string is empty")
31+
}
32+
33+
// Check if the hexadecimal string is valid
34+
if !isValidHex(hex) {
35+
return "", errors.New("invalid hexadecimal string: " + hex)
36+
}
37+
38+
// Parse the hexadecimal string to an integer
39+
var decimal int64
40+
for i := 0; i < len(hex); i++ {
41+
char := hex[i]
42+
var value int64
43+
if char >= '0' && char <= '9' {
44+
value = int64(char - '0')
45+
} else if char >= 'A' && char <= 'F' {
46+
value = int64(char - 'A' + 10)
47+
} else if char >= 'a' && char <= 'f' {
48+
value = int64(char - 'a' + 10)
49+
} else {
50+
return "", errors.New("invalid character in hexadecimal string: " + string(char))
51+
}
52+
decimal = decimal*16 + value
53+
}
54+
55+
// Convert the integer to a binary string without using predefined functions
56+
var binaryBuilder strings.Builder
57+
if decimal == 0 {
58+
binaryBuilder.WriteString("0")
59+
} else {
60+
for decimal > 0 {
61+
bit := decimal % 2
62+
if bit == 0 {
63+
binaryBuilder.WriteString("0")
64+
} else {
65+
binaryBuilder.WriteString("1")
66+
}
67+
decimal = decimal / 2
68+
}
69+
}
70+
71+
// Reverse the binary string since the bits are added in reverse order
72+
binaryRunes := []rune(binaryBuilder.String())
73+
for i, j := 0, len(binaryRunes)-1; i < j; i, j = i+1, j-1 {
74+
binaryRunes[i], binaryRunes[j] = binaryRunes[j], binaryRunes[i]
75+
}
76+
77+
return string(binaryRunes), nil
78+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package conversion
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestHexToBinary(t *testing.T) {
8+
tests := []struct {
9+
hex string
10+
want string
11+
wantErr bool
12+
}{
13+
{"", "", true},
14+
{"G123", "", true},
15+
{"12XZ", "", true},
16+
{"1", "1", false},
17+
{"A", "1010", false},
18+
{"10", "10000", false},
19+
{"1A", "11010", false},
20+
{"aB", "10101011", false},
21+
{"0Ff", "11111111", false},
22+
{" 1A ", "11010", false},
23+
{"0001A", "11010", false},
24+
{"7FFFFFFFFFFFFFFF", "111111111111111111111111111111111111111111111111111111111111111", false},
25+
}
26+
27+
for _, tt := range tests {
28+
t.Run(tt.hex, func(t *testing.T) {
29+
got, err := hexToBinary(tt.hex)
30+
if (err != nil) != tt.wantErr {
31+
t.Errorf("hexToBinary(%q) error = %v, wantErr %v", tt.hex, err, tt.wantErr)
32+
return
33+
}
34+
if got != tt.want {
35+
t.Errorf("hexToBinary(%q) = %v, want %v", tt.hex, got, tt.want)
36+
}
37+
})
38+
}
39+
}
40+
41+
func BenchmarkHexToBinary(b *testing.B) {
42+
b.ReportAllocs()
43+
for i := 0; i < b.N; i++ {
44+
_, _ = hexToBinary("7FFFFFFFFFFFFFFF")
45+
}
46+
}

conversion/hexadecimaltodecimal.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Author: mapcrafter2048
3+
GitHub: https://github.com/mapcrafter2048
4+
*/
5+
6+
// This algorithm will convert any Hexadecimal number(0-9, A-F, a-f) to Decimal number(0-9).
7+
// https://en.wikipedia.org/wiki/Hexadecimal
8+
// https://en.wikipedia.org/wiki/Decimal
9+
// Function receives a Hexadecimal Number as string and returns the Decimal number as integer.
10+
// Supported Hexadecimal number range is 0 to 7FFFFFFFFFFFFFFF.
11+
12+
package conversion
13+
14+
import (
15+
"fmt"
16+
"regexp"
17+
"strings"
18+
)
19+
20+
var isValidHexadecimal = regexp.MustCompile("^[0-9A-Fa-f]+$").MatchString
21+
22+
// hexToDecimal converts a hexadecimal string to a decimal integer.
23+
func hexToDecimal(hexStr string) (int64, error) {
24+
25+
hexStr = strings.TrimSpace(hexStr)
26+
27+
if len(hexStr) == 0 {
28+
return 0, fmt.Errorf("input string is empty")
29+
}
30+
31+
// Check if the string has a valid hexadecimal prefix
32+
if len(hexStr) > 2 && (hexStr[:2] == "0x" || hexStr[:2] == "0X") {
33+
hexStr = hexStr[2:]
34+
}
35+
36+
// Validate the hexadecimal string
37+
if !isValidHexadecimal(hexStr) {
38+
return 0, fmt.Errorf("invalid hexadecimal string")
39+
}
40+
41+
var decimalValue int64
42+
for _, char := range hexStr {
43+
var digit int64
44+
if char >= '0' && char <= '9' {
45+
digit = int64(char - '0')
46+
} else if char >= 'A' && char <= 'F' {
47+
digit = int64(char - 'A' + 10)
48+
} else if char >= 'a' && char <= 'f' {
49+
digit = int64(char - 'a' + 10)
50+
} else {
51+
return 0, fmt.Errorf("invalid character in hexadecimal string: %c", char)
52+
}
53+
decimalValue = decimalValue*16 + digit
54+
}
55+
56+
return decimalValue, nil
57+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package conversion
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestHexToDecimal(t *testing.T) {
8+
tests := []struct {
9+
hex string
10+
want int64
11+
wantErr bool
12+
}{
13+
{"", 0, true},
14+
{"G123", 0, true},
15+
{"123Z", 0, true},
16+
{"1", 1, false},
17+
{"A", 10, false},
18+
{"10", 16, false},
19+
{"1A", 26, false},
20+
{"aB", 171, false},
21+
{"0Ff", 255, false},
22+
{" 1A ", 26, false},
23+
{"0x1A", 26, false},
24+
{"0X1A", 26, false},
25+
{"1A", 26, false},
26+
{"7FFFFFFFFFFFFFFF", 9223372036854775807, false},
27+
{"0001A", 26, false},
28+
{"0000007F", 127, false},
29+
{"0", 0, false},
30+
{"0x0", 0, false},
31+
}
32+
33+
for _, tt := range tests {
34+
t.Run(tt.hex, func(t *testing.T) {
35+
got, err := hexToDecimal(tt.hex)
36+
if (err != nil) != tt.wantErr {
37+
t.Errorf("hexToDecimal(%q) error = %v, wantErr %v", tt.hex, err, tt.wantErr)
38+
return
39+
}
40+
if got != tt.want {
41+
t.Errorf("hexToDecimal(%q) = %v, want %v", tt.hex, got, tt.want)
42+
}
43+
})
44+
}
45+
}
46+
47+
func BenchmarkHexToDecimal(b *testing.B) {
48+
b.ReportAllocs()
49+
for i := 0; i < b.N; i++ {
50+
_, _ = hexToDecimal("7FFFFFFFFFFFFFFF")
51+
}
52+
}

0 commit comments

Comments
 (0)