As the title explains, how could I create a function func
(using numpy or math modules) to find the nearest member of the geometric sequence (2, 4, 8, 16, 32, 64, 128 . . . )?
For example, func(3)
should yield 2, func(20)
should yield 16, and func(128)
should yield 128.
I cannot find any information on this problem. Most rounding problems discuss rounding to the nearest multiple of some number, rather than to the nearest member of a geometric sequence.
CodePudding user response:
Use the concept of power and log
import numpy as np
def round_to_geometric(x):
return int(2 ** np.floor(np.log2(x)))
output:
> print(round_to_geometric(3))
> print(round_to_geometric(20))
> print(round_to_geometric(128))
2
16
128
CodePudding user response:
One way to think about this is in terms of the length of a binary representation of an integer:
def myround(i):
return 2 ** (len(bin(i)) - 3)
>>> [myround(i) for i in (3, 4, 5, 6, 7, 8, 20, 25, 128)]
[2, 4, 4, 4, 4, 8, 16, 16, 128]
Explanation: bin(x)
returns a binary string representation of the input.
>>> bin(20)
'0b10100'
The length of this representation depends on the most significant bit in the sequence. For bin(20)
, the most significant bit is 16 (or 2 ** 4
). Subtracting 3 ignores the 0b
and the 1s
place in the binary string. So len(bin(20)) - 3 = 4