Skip to content

Commit

Permalink
feat: Binary to Decimal Conversion (#398)
Browse files Browse the repository at this point in the history
  • Loading branch information
motasimmakki authored Oct 23, 2021
1 parent 5f9d41b commit 18451c6
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
* [Roman Numeral To Integer](./conversion/romantointeger.go)
* [Integer To Roman Numeral](./conversion/integertoroman.go)
* [Decimal To Binary](./conversion/decimaltobinary.go)
* [Binary To Decimal](./conversion/binarytodecimal.go)

### Data Structures
* [AVL Tree](./structure/avl/avl.go)
Expand Down
41 changes: 41 additions & 0 deletions conversion/binarytodecimal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Author: Motasim
GitHub: https://github.com/motasimmakki
Date: 19-Oct-2021
*/

// This algorithm will convert any Binary number(0 or 1) to Decimal number(+ve number).
// https://en.wikipedia.org/wiki/Binary_number
// https://en.wikipedia.org/wiki/Decimal
// Function receives a Binary Number as string and returns the Decimal number as integer.
// Suppoted Binary number range is 0 to 2^(31-1).

// Package name.
package conversion

// Importing necessary package.
import (
"errors"
"regexp"
)

var isValid = regexp.MustCompile("^[0-1]{1,}$").MatchString

// BinaryToDecimal() function that will take Binary number as string,
// and return it's Decimal equivalent as integer.
func BinaryToDecimal(binary string) (int, error) {
if !isValid(binary) {
return -1, errors.New("not a valid binary string")
}
if len(binary) > 32 {
return -1, errors.New("binary number must be in range 0 to 2^(31-1)")
}
var result, base int = 0, 1
for i := len(binary) - 1; i >= 0; i-- {
if binary[i] == '1' {
result += base
}
base *= 2
}
return result, nil
}
46 changes: 46 additions & 0 deletions conversion/binarytodecimal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package conversion

import "testing"

var binaryTestCases = map[string]int{
"0": 0, "1": 1, "10": 2, "11": 3, "100": 4,
"101": 5, "110": 6, "111": 7, "1000": 8, "1001": 9,
"1010": 10, "1011": 11, "1100": 12, "1101": 13, "1110": 14,
"1111": 15, "10000": 16, "10001": 17, "10010": 18, "10011": 19,
"10100": 20, "10101": 21, "10110": 22, "10111": 23, "11000": 24,
"11001": 25, "11010": 26, "11011": 27, "11100": 28, "11101": 29,
"11110": 30, "11111": 31, "100000": 32, "100001": 33, "100010": 34,
"100011": 35, "100100": 36, "100101": 37, "100110": 38, "100111": 39,
"101000": 40, "101001": 41, "101010": 42, "101011": 43, "101100": 44,
"101101": 45, "101110": 46, "101111": 47, "110000": 48, "110001": 49,
"110010": 50, "110011": 51, "110100": 52, "110101": 53, "110110": 54,
"110111": 55, "111000": 56, "111001": 57, "111010": 58, "111011": 59,
"111100": 60, "111101": 61, "111110": 62, "111111": 63, "1000000": 64,
"1000001": 65, "1000010": 66, "1000011": 67, "1000100": 68, "1000101": 69,
"1000110": 70, "1000111": 71, "1001000": 72, "1001001": 73, "1001010": 74,
"1001011": 75, "1001100": 76, "1001101": 77, "1001110": 78, "1001111": 79,
"1010000": 80, "1010001": 81, "1010010": 82, "1010011": 83, "1010100": 84,
"1010101": 85, "1010110": 86, "1010111": 87, "1011000": 88, "1011001": 89,
"1011010": 90, "1011011": 91, "1011100": 92, "1011101": 93, "1011110": 94,
"1011111": 95, "1100000": 96, "1100001": 97, "1100010": 98, "1100011": 99,
"1100100": 100,
}

func TestBinaryToDecimal(t *testing.T) {
for input, expected := range binaryTestCases {
out, err := BinaryToDecimal(input)
if err != nil {
t.Errorf("BinaryToDecimal(%s) returned an error %s", input, err.Error())
}
if out != expected {
t.Errorf("BinaryToDecimal(%s) = %d; want %d", input, out, expected)
}
}
}

func BenchmarkBinaryToDecimal(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, _ = BinaryToDecimal("1100100")
}
}
12 changes: 6 additions & 6 deletions conversion/decimaltobinary.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ import (
"strconv"
)

// Inverse() function that will take string,
// and returns the inverse of that string.
func Inverse(str string) string {
// Reverse() function that will take string,
// and returns the reverse of that string.
func Reverse(str string) string {
rStr := []rune(str)
for i, j := 0, len(rStr)-1; i < len(rStr)/2; i, j = i+1, j-1 {
rStr[i], rStr[j] = rStr[j], rStr[i]
}
return string(rStr)
}

// Convert() function that will take Decimal number as int,
// DecimalToBinary() function that will take Decimal number as int,
// and return it's Binary equivalent as string.
func Convert(num int) (string, error) {
func DecimalToBinary(num int) (string, error) {
if num < 0 {
return "", errors.New("integer must have +ve value")
}
Expand All @@ -42,5 +42,5 @@ func Convert(num int) (string, error) {
result += strconv.Itoa(num & 1)
num >>= 1
}
return Inverse(result), nil
return Reverse(result), nil
}
12 changes: 6 additions & 6 deletions conversion/decimaltobinary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ var decimalTestCases = map[int]string{
100: "1100100",
}

func TestConvert(t *testing.T) {
func TestDecimalToBinary(t *testing.T) {
for input, expected := range decimalTestCases {
out, err := Convert(input)
out, err := DecimalToBinary(input)
if err != nil {
t.Errorf("Convert(%d) returned an error %s", input, err.Error())
t.Errorf("DecimalToBinary(%d) returned an error %s", input, err.Error())
}
if out != expected {
t.Errorf("Convert(%d) = %s; want %s", input, out, expected)
t.Errorf("DecimalToBinary(%d) = %s; want %s", input, out, expected)
}
}
}

func BenchmarkConvert(b *testing.B) {
func BenchmarkDecimalToBinary(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, _ = Convert(100)
_, _ = DecimalToBinary(100)
}
}

0 comments on commit 18451c6

Please sign in to comment.