Skip to content

Commit

Permalink
Abs algo (TheAlgorithms#453)
Browse files Browse the repository at this point in the history
* feat: bitwise min

* fix: bitwise min, change for vararg

* fix: change min tests

* fix: benchmark for bitwise

* fix: rename tests

* fix: add value param

* fix: change condition

* feat: added description to some functions

* Updated Documentation in README.md

* fix: change descriptions

* Updated Documentation in README.md

* Updated Documentation in README.md

* Updated Documentation in README.md

* feat: abs algo

* Updated Documentation in README.md

* fix: add comment

* Updated Documentation in README.md

* fix: new comment

* Updated Documentation in README.md

* fix: rename func and remove package

* Updated Documentation in README.md

* Update math/abs.go

Co-authored-by: Taj <tjgurwara99@users.noreply.github.com>

* Updated Documentation in README.md

* Update math/binary/abs.go

Co-authored-by: Taj <tjgurwara99@users.noreply.github.com>

* Updated Documentation in README.md

* fix: rename func and move binary test

Co-authored-by: Rak Laptudirm <raklaptudirm@gmail.com>
Co-authored-by: github-action <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: Taj <tjgurwara99@users.noreply.github.com>
  • Loading branch information
4 people authored Dec 23, 2021
1 parent 7fcbe26 commit 75b615c
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 10 deletions.
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,15 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
---
##### Functions:

1. [`BitCounter`](./math/binary/bitcounter.go#L11): BitCounter - The function returns the number of set bits for an unsigned integer number
2. [`IsPowerOfTwo`](./math/binary/checkisnumberpoweroftwo.go#L19): IsPowerOfTwo This function uses the fact that powers of 2 are represented like 10...0 in binary, and numbers one less than the power of 2 are represented like 11...1. Therefore, using the and function: 10...0 & 01...1 00...0 -> 0 This is also true for 0, which is not a power of 2, for which we have to add and extra condition.
3. [`IsPowerOfTwoLeftShift`](./math/binary/checkisnumberpoweroftwo.go#L26): IsPowerOfTwoLeftShift This function takes advantage of the fact that left shifting a number by 1 is equivalent to multiplying by 2. For example, binary 00000001 when shifted by 3 becomes 00001000, which in decimal system is 8 or = 2 * 2 * 2
4. [`MeanUsingAndXor`](./math/binary/arithmeticmean.go#L12): MeanUsingAndXor This function finds arithmetic mean using "AND" and "XOR" operations
5. [`MeanUsingRightShift`](./math/binary/arithmeticmean.go#L17): MeanUsingRightShift This function finds arithmetic mean using right shift
6. [`ReverseBits`](./math/binary/reversebits.go#L14): ReverseBits This function initialized the result by 0 (all bits 0) and process the given number starting from its least significant bit. If the current bit is 1, set the corresponding most significant bit in the result and finally move on to the next bit in the input number. Repeat this till all its bits are processed.
7. [`SequenceGrayCode`](./math/binary/rbc.go#L11): SequenceGrayCode The function generates an "Gray code" sequence of length n
8. [`XorSearchMissingNumber`](./math/binary/xorsearch.go#L11): XorSearchMissingNumber This function finds a missing number in a sequence
1. [`Abs`](./math/binary/abs.go#L10): Abs returns absolute value using binary operation Principle of operation: 1) Get the mask by right shift by the base 2) Base is the size of an integer variable in bits, for example, for int32 it will be 32, for int64 it will be 64 3) For negative numbers, above step sets mask as 1 1 1 1 1 1 1 1 and 0 0 0 0 0 0 0 0 for positive numbers. 4) Add the mask to the given number. 5) XOR of mask + n and mask gives the absolute value.
2. [`BitCounter`](./math/binary/bitcounter.go#L11): BitCounter - The function returns the number of set bits for an unsigned integer number
3. [`IsPowerOfTwo`](./math/binary/checkisnumberpoweroftwo.go#L19): IsPowerOfTwo This function uses the fact that powers of 2 are represented like 10...0 in binary, and numbers one less than the power of 2 are represented like 11...1. Therefore, using the and function: 10...0 & 01...1 00...0 -> 0 This is also true for 0, which is not a power of 2, for which we have to add and extra condition.
4. [`IsPowerOfTwoLeftShift`](./math/binary/checkisnumberpoweroftwo.go#L26): IsPowerOfTwoLeftShift This function takes advantage of the fact that left shifting a number by 1 is equivalent to multiplying by 2. For example, binary 00000001 when shifted by 3 becomes 00001000, which in decimal system is 8 or = 2 * 2 * 2
5. [`MeanUsingAndXor`](./math/binary/arithmeticmean.go#L12): MeanUsingAndXor This function finds arithmetic mean using "AND" and "XOR" operations
6. [`MeanUsingRightShift`](./math/binary/arithmeticmean.go#L17): MeanUsingRightShift This function finds arithmetic mean using right shift
7. [`ReverseBits`](./math/binary/reversebits.go#L14): ReverseBits This function initialized the result by 0 (all bits 0) and process the given number starting from its least significant bit. If the current bit is 1, set the corresponding most significant bit in the result and finally move on to the next bit in the input number. Repeat this till all its bits are processed.
8. [`SequenceGrayCode`](./math/binary/rbc.go#L11): SequenceGrayCode The function generates an "Gray code" sequence of length n
9. [`XorSearchMissingNumber`](./math/binary/xorsearch.go#L11): XorSearchMissingNumber This function finds a missing number in a sequence

---
</details><details>
Expand Down Expand Up @@ -521,8 +522,9 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
---
##### Functions:

1. [`IsPowOfTwoUseLog`](./math/checkisnumberpoweroftwo.go#L10): IsPowOfTwoUseLog This function checks if a number is a power of two using the logarithm. The limiting degree can be from 0 to 63. See alternatives in the binary package.
2. [`Phi`](./math/eulertotient.go#L5): Phi is the Euler totient function. This function computes the number of numbers less then n that are coprime with n.
1. [`Abs`](./math/abs.go#L11): Abs returns absolute value
2. [`IsPowOfTwoUseLog`](./math/checkisnumberpoweroftwo.go#L10): IsPowOfTwoUseLog This function checks if a number is a power of two using the logarithm. The limiting degree can be from 0 to 63. See alternatives in the binary package.
3. [`Phi`](./math/eulertotient.go#L5): Phi is the Euler totient function. This function computes the number of numbers less then n that are coprime with n.

---
</details><details>
Expand Down
16 changes: 16 additions & 0 deletions math/abs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// abs.go
// description: Absolute value
// details:
// In mathematics, the absolute value or modulus of a real number x, denoted |x|, is the non-negative value of x without regard to its sign. [Absolute value](https://en.wikipedia.org/wiki/Average#Arithmetic_mean)
// author(s) [red_byte](https://github.com/i-redbyte)
// see abs_test.go

package math

// Abs returns absolute value
func Abs(n int) int {
if n < 0 {
return -n
}
return n
}
61 changes: 61 additions & 0 deletions math/abs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package math

import (
"github.com/TheAlgorithms/Go/math/binary"
"math"
"testing"
)

func TestAbs(t *testing.T) {
tests := getTests()
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := Abs(test.n); got != test.want {
t.Errorf("Abs() = %v, want %v", got, test.want)
}
})
}
}

func getTests() []struct {
name string
n int
want int
} {
tests := []struct {
name string
n int
want int
}{
{"-1 = |1| ", -1, 1},
{"-255 = |255| ", -255, 255},
{"0 = |0| ", 0, 0},
{"5 = |5| ", 5, 5},
{"-5 = |5| ", -5, 5},
{"-98368972 = |98368972| ", -98368972, 98368972},
}
return tests
}

func BenchmarkSimpleAbs(b *testing.B) {
for i := 0; i < b.N; i++ {
Abs(-1024)
}
}
func BenchmarkBinaryAbs32(b *testing.B) {
for i := 0; i < b.N; i++ {
binary.Abs(32, -1024)
}
}

func BenchmarkBinaryAbs64(b *testing.B) {
for i := 0; i < b.N; i++ {
binary.Abs(64, -1024)
}
}

func BenchmarkStdLibAbs(b *testing.B) {
for i := 0; i < b.N; i++ {
math.Abs(-1024)
}
}
13 changes: 13 additions & 0 deletions math/binary/abs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package binary

// Abs returns absolute value using binary operation
// Principle of operation:
// 1) Get the mask by right shift by the base
// 2) Base is the size of an integer variable in bits, for example, for int32 it will be 32, for int64 it will be 64
// 3) For negative numbers, above step sets mask as 1 1 1 1 1 1 1 1 and 0 0 0 0 0 0 0 0 for positive numbers.
// 4) Add the mask to the given number.
// 5) XOR of mask + n and mask gives the absolute value.
func Abs(base, n int) int {
m := n >> (base - 1)
return (n + m) ^ m
}
37 changes: 37 additions & 0 deletions math/binary/abs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package binary

import "testing"

func TestAbs(t *testing.T) {
tests := getAbsTests()
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := Abs(test.base, test.n); got != test.want {
t.Errorf("Abs() = %v, want %v", got, test.want)
}
})
}
}

func getAbsTests() []struct {
name string
base int
n int
want int
} {
tests := []struct {
name string
base int
n int
want int
}{
{"-1 = |1| ", 32, -1, 1},
{"-255 = |255| ", 32, -255, 255},
{"0 = |0| ", 64, 0, 0},
{"5 = |5| ", 16, 5, 5},
{"-5 = |5| ", 32, -5, 5},
{"-98368972 = |98368972| ", 64, -98368972, 98368972},
{"-110298368972 = |110298368972| ", 64, -98368972, 98368972},
}
return tests
}

0 comments on commit 75b615c

Please sign in to comment.