Packages
common_twos
1.0.0
A utility library for finding common factors of 2 between two numbers using efficient bitwise operations.
Current section
Files
Jump to
Current section
Files
lib/common_twos.ex
defmodule CommonTwos do
@moduledoc """
A utility module for finding the greatest common divisor (GCD) of two numbers
by counting trailing zeros in their binary representation.
This module provides efficient algorithms for finding common factors between
two integers using bitwise operations. The primary function `of/2` returns
a tuple containing the shift count and the reduced values after removing
common factors of 2.
## Examples
iex> CommonTwos.of(12, 8)
{2, 3, 2}
iex> CommonTwos.of(16, 24)
{3, 2, 3}
iex> CommonTwos.of(7, 11)
{0, 7, 11}
## Algorithm
The algorithm works by:
1. Counting how many trailing zeros both numbers have in common
2. Shifting both numbers right by that amount
3. Returning the shift count and the reduced numbers
This is particularly useful for:
- Finding common factors efficiently
- Optimizing mathematical operations
- Number theory applications
"""
@doc """
Finds the common factors of 2 between two numbers and returns the shift count
along with the reduced values.
## Parameters
- `a` - First non-negative integer
- `b` - Second non-negative integer
## Returns
A tuple `{shift, reduced_a, reduced_b}` where:
- `shift` - The number of common factors of 2 (trailing zeros in binary)
- `reduced_a` - The value of `a` after removing common factors of 2
- `reduced_b` - The value of `b` after removing common factors of 2
## Examples
iex> CommonTwos.of(12, 8)
{2, 3, 2}
iex> CommonTwos.of(16, 24)
{3, 2, 3}
iex> CommonTwos.of(7, 11)
{0, 7, 11}
iex> CommonTwos.of(0, 8)
{3, 0, 1}
## Notes
- If both numbers are 0, the result will be `{0, 0, 0}`
- If one number is 0, the shift count will be based on the non-zero number
- The algorithm uses bitwise operations for efficiency
"""
@spec of(non_neg_integer(), non_neg_integer()) ::
{non_neg_integer(), non_neg_integer(), non_neg_integer()}
def of(a, b), do: sub({0, a, b})
# Private function that performs the recursive bitwise operations
# to find common factors of 2 between the two numbers
defp sub({shift, a, b}) when Bitwise.bor(a, b) |> Bitwise.band(1) != 0 do
{shift, a, b}
end
defp sub({shift, a, b}), do: sub({shift + 1, Bitwise.bsr(a, 1), Bitwise.bsr(b, 1)})
end