Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth
Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Boost your online presence with premium web hosting and servers

Disclosure: My content contains affiliate links.

42,690 questions

55,449 answers

573 users

How to round a number to the nearest power of 2 in Ruby

1 Answer

0 votes
# ================================================================
#  round_to_power_of_two(n)
#  -------------------------
#  Rounds the integer *n* to the nearest power of 2.
#
#  Explanation:
#    A power of 2 is any number of the form 2^k.
#    Examples: 1, 2, 4, 8, 16, 32, 64, ...
#
#  Strategy (efficient and idiomatic Ruby):
#    • If n <= 1, the nearest power of 2 is 1.
#    • Otherwise, compute:
#         lower = 2^floor(log2(n))
#         upper = 2^ceil(log2(n))
#      Then choose whichever of lower or upper is closer to n.
#
#  Ruby provides:
#    • Math.log2(x) → base‑2 logarithm
#    • Integer#**   → exponentiation
#
#  This algorithm runs in O(1) time.
# ================================================================

def round_to_power_of_two(n)
  # Defensive programming: handle non-positive values.
  return 1 if n <= 1

  # Compute the base‑2 logarithm.
  log2 = Math.log2(n)

  # Find the nearest lower and upper powers of 2.
  lower = 2 ** log2.floor
  upper = 2 ** log2.ceil

  # Choose whichever is closer to n.
  # If exactly in the middle, Ruby will pick the lower one.
  (n - lower).abs <= (upper - n).abs ? lower : upper
end

# ================================================================
# Demonstration
# ================================================================

values = [1, 2, 3, 5, 7, 12, 20, 37, 70, 129, 255, 300, 513, 1025]

values.each do |v|
  puts "round_to_power_of_two(#{v}) = #{round_to_power_of_two(v)}"
end


# run:
#
# round_to_power_of_two(1) = 1
# round_to_power_of_two(2) = 2
# round_to_power_of_two(3) = 2
# round_to_power_of_two(5) = 4
# round_to_power_of_two(7) = 8
# round_to_power_of_two(12) = 8
# round_to_power_of_two(20) = 16
# round_to_power_of_two(37) = 32
# round_to_power_of_two(70) = 64
# round_to_power_of_two(129) = 128
# round_to_power_of_two(255) = 256
# round_to_power_of_two(300) = 256
# round_to_power_of_two(513) = 512
# round_to_power_of_two(1025) = 1024
#

 



answered Jul 22 by avibootz
...