How to calculate integer logarithm of base 3, using fast bit operations? - bit-manipulation

Calculating of integer logarithm base 2 is pretty easy in near any computer language - you just find the largest '1' in binary representation, and rest becomes zero.
Is is possible to do the same fast trick for other bases, for example 3, - calculate logarithm of base 3 or get the nearest integer from below what is correct 3n?

Yes, using the same method as Find integer log base 10 of an integer we can achieve the same thing. We just need to replace powers of 10 with powers of 3, log102 with log32, and a multiplication of 1⁄log32 ≈ ³²³⁄₅₁₂ is used
Here's a simple PoC in JavaScript that you can try live in the browser. See the function ilog3()
const POW3 = new Int32Array([ 1, 3, 9, 27, 81, 243, 729,
2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969,
14348907, 43046721, 129140163, 387420489, 1162261467 ])
function ilog2(x) {
// Here floating-point log is used because JavaScript doesn't have
// find-first-set/count-leading-zero/integer-log-2/whatever
// to get the position of the most significant bit.
// On platforms/languages with that feature we should use that instead
return Math.trunc(Math.log2(x))
}
function ilog3(x) {
let t = (ilog2(x) + 1)*323 >>> 9
return t - (x < POW3[t])
}
allOK = true
const Log3 = Math.log(3)
function check(x) {
a = ilog3(x);
b = Math.trunc(Math.log(x)/Log3);
if (a != b) {
console.log([x, a, b])
allOK = false
}
}
function checkAll(x) {
if (x > 1) { check(x - 1) }
check(x)
check(x + 1)
}
// Check if log3(x - 1), log3(x), log3(x + 1) are correct
// for all x that are powers of 3
POW3.forEach(checkAll)
if (allOK) { console.log("OK") }

Related

I need to get a random number in the range from a to b with n decimal places

I need a function that returns me a random number with n decimal places
Example:
int aleatorio(int li, int ls)
{
return rand()%(ls+1-li)+li;
}
What i want is:
float new_random(int start, int final, int number_decimals)
{
return // What should I write here?
}
if I would call this function 5 times like this::
new_random(0, 5, 4);
The exit would be:
0.2344
3.4356
2.8435
4.2435
I do not want to use this, because I need numbers of 4 exact decimal places since I will not use them to print, but you will have others:
cout << setprecision(4) << 4.24359675967 << endl; //I do not want this
I need numbers of 4 exact decimal places
Then you cannot use finite precision binary floating point (i.e. float, double or long double) because those types cannot exactly represent all of the values with 4 decimal places.
A solution is to use arbitrary precision floating point, and another is to use fixed point. C++ standard doesn't provide arbitrary precision types nor fixed point types. Another approach is to give up the requirement of exactly representing those values and accept the almost exact values that are achievable with limited precision.
Try this for a Java solution. Multiply the start and finish by 1000, generating ints between the range and then divide the resultant number by 1000 as a double.
int start = 20;
int finish = 30;
int count = 10;
Random r = new Random();
r.ints(start * 1000, finish * 1000).filter(n -> n % 10 != 0)
.limit(count).mapToDouble(n -> n / 1000.)
.forEach(System.out::println);
prints something like this.
21.186
26.983
25.345
20.764
27.911
21.139
24.679
27.722
29.443
28.675
Or as a method supplying the starting number, ending number and precision.
for (int i = 0; i < 10; i++) {
System.out.println(newRandom(start,finish,4));
}
static Random r = new Random();
public static Double newRandom(int start, int finish, int precision) {
int f = (int)Math.pow(10,precision);
return r.ints(start * f, finish * f).filter(n -> n % 10 != 0)
.limit(1).mapToDouble(n -> n / (double)f).findFirst().getAsDouble();
}
Prints something like this.
28.4444
25.0259
29.5611
25.6445
25.4977
28.5124
28.9709
23.4835
27.9766
23.9438
You can generate an integer number N between start and final * 10^number_decimals and then return N / 10^number_decimals
Eg. start = 0, final = 5, number_decimals = 4 ==> N in [0 - 50000] ==> N/10000 in [0.0000 - 5.0000]
float new_random(int start, int final, int number_decimals) {
return aleatorio(start, final*pow10(number_decimals))/number_decimals;
}
You can define pow10 as:
int pow10(int p) {
if (p == 0) return 1;
else return 10 * pow10(p-1);
}

How to store output of very large Fibonacci number?

I am making a program for nth Fibonacci number. I made the following program using recursion and memoization.
The main problem is that the value of n can go up to 10000 which means that the Fibonacci number of 10000 would be more than 2000 digit long.
With a little bit of googling, I found that i could use arrays and store every digit of the solution in an element of the array but I am still not able to figure out how to implement this approach with my program.
#include<iostream>
using namespace std;
long long int memo[101000];
long long int n;
long long int fib(long long int n)
{
if(n==1 || n==2)
return 1;
if(memo[n]!=0)
return memo[n];
return memo[n] = fib(n-1) + fib(n-2);
}
int main()
{
cin>>n;
long long int ans = fib(n);
cout<<ans;
}
How do I implement that approach or if there is another method that can be used to achieve such large values?
One thing that I think should be pointed out is there's other ways to implement fib that are much easier for something like C++ to compute
consider the following pseudo code
function fib (n) {
let a = 0, b = 1, _;
while (n > 0) {
_ = a;
a = b;
b = b + _;
n = n - 1;
}
return a;
}
This doesn't require memoisation and you don't have to be concerned about blowing up your stack with too many recursive calls. Recursion is a really powerful looping construct but it's one of those fubu things that's best left to langs like Lisp, Scheme, Kotlin, Lua (and a few others) that support it so elegantly.
That's not to say tail call elimination is impossible in C++, but unless you're doing something to optimise/compile for it explicitly, I'm doubtful that whatever compiler you're using would support it by default.
As for computing the exceptionally large numbers, you'll have to either get creative doing adding The Hard Way or rely upon an arbitrary precision arithmetic library like GMP. I'm sure there's other libs for this too.
Adding The Hard Way™
Remember how you used to add big numbers when you were a little tater tot, fresh off the aluminum foil?
5-year-old math
1259601512351095520986368
+ 50695640938240596831104
---------------------------
?
Well you gotta add each column, right to left. And when a column overflows into the double digits, remember to carry that 1 over to the next column.
... <-001
1259601512351095520986368
+ 50695640938240596831104
---------------------------
... <-472
The 10,000th fibonacci number is thousands of digits long, so there's no way that's going to fit in any integer C++ provides out of the box. So without relying upon a library, you could use a string or an array of single-digit numbers. To output the final number, you'll have to convert it to a string tho.
(woflram alpha: fibonacci 10000)
Doing it this way, you'll perform a couple million single-digit additions; it might take a while, but it should be a breeze for any modern computer to handle. Time to get to work !
Here's an example in of a Bignum module in JavaScript
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
We can verify that the Wolfram Alpha answer above is correct
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
bigfib (10000)
// "336447 ... 366875"
Expand the program below to run it in your browser
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
console.log (bigfib (10000))
Try not to use recursion for a simple problem like fibonacci. And if you'll only use it once, don't use an array to store all results. An array of 2 elements containing the 2 previous fibonacci numbers will be enough. In each step, you then only have to sum up those 2 numbers. How can you save 2 consecutive fibonacci numbers? Well, you know that when you have 2 consecutive integers one is even and one is odd. So you can use that property to know where to get/place a fibonacci number: for fib(i), if i is even (i%2 is 0) place it in the first element of the array (index 0), else (i%2 is then 1) place it in the second element(index 1). Why can you just place it there? Well when you're calculating fib(i), the value that is on the place fib(i) should go is fib(i-2) (because (i-2)%2 is the same as i%2). But you won't need fib(i-2) any more: fib(i+1) only needs fib(i-1)(that's still in the array) and fib(i)(that just got inserted in the array).
So you could replace the recursion calls with a for loop like this:
int fibonacci(int n){
if( n <= 0){
return 0;
}
int previous[] = {0, 1}; // start with fib(0) and fib(1)
for(int i = 2; i <= n; ++i){
// modulo can be implemented with bit operations(much faster): i % 2 = i & 1
previous[i&1] += previous[(i-1)&1]; //shorter way to say: previous[i&1] = previous[i&1] + previous[(i-1)&1]
}
//Result is in previous[n&1]
return previous[n&1];
}
Recursion is actually discommanded while programming because of the time(function calls) and ressources(stack) it consumes. So each time you use recursion, try to replace it with a loop and a stack with simple pop/push operations if needed to save the "current position" (in c++ one can use a vector). In the case of the fibonacci, the stack isn't even needed but if you are iterating over a tree datastructure for example you'll need a stack (depends on the implementation though). As I was looking for my solution, I saw #naomik provided a solution with the while loop. That one is fine too, but I prefer the array with the modulo operation (a bit shorter).
Now concerning the problem of the size long long int has, it can be solved by using external libraries that implement operations for big numbers (like the GMP library or Boost.multiprecision). But you could also create your own version of a BigInteger-like class from Java and implement the basic operations like the one I have. I've only implemented the addition in my example (try to implement the others they are quite similar).
The main idea is simple, a BigInt represents a big decimal number by cutting its little endian representation into pieces (I'll explain why little endian at the end). The length of those pieces depends on the base you choose. If you want to work with decimal representations, it will only work if your base is a power of 10: if you choose 10 as base each piece will represent one digit, if you choose 100 (= 10^2) as base each piece will represent two consecutive digits starting from the end(see little endian), if you choose 1000 as base (10^3) each piece will represent three consecutive digits, ... and so on. Let's say that you have base 100, 12765 will then be [65, 27, 1], 1789 will be [89, 17], 505 will be [5, 5] (= [05,5]), ... with base 1000: 12765 would be [765, 12], 1789 would be [789, 1], 505 would be [505]. It's not the most efficient, but it is the most intuitive (I think ...)
The addition is then a bit like the addition on paper we learned at school:
begin with the lowest piece of the BigInt
add it with the corresponding piece of the other one
the lowest piece of that sum(= the sum modulus the base) becomes the corresponding piece of the final result
the "bigger" pieces of that sum will be added ("carried") to the sum of the following pieces
go to step 2 with next piece
if no piece left, add the carry and the remaining bigger pieces of the other BigInt (if it has pieces left)
For example:
9542 + 1097855 = [42, 95] + [55, 78, 09, 1]
lowest piece = 42 and 55 --> 42 + 55 = 97 = [97]
---> lowest piece of result = 97 (no carry, carry = 0)
2nd piece = 95 and 78 --> (95+78) + 0 = 173 = [73, 1]
---> 2nd piece of final result = 73
---> remaining: [1] = 1 = carry (will be added to sum of following pieces)
no piece left in first `BigInt`!
--> add carry ( [1] ) and remaining pieces from second `BigInt`( [9, 1] ) to final result
--> first additional piece: 9 + 1 = 10 = [10] (no carry)
--> second additional piece: 1 + 0 = 1 = [1] (no carry)
==> 9542 + 1 097 855 = [42, 95] + [55, 78, 09, 1] = [97, 73, 10, 1] = 1 107 397
Here is a demo where I used the class above to calculate the fibonacci of 10000 (result is too big to copy here)
Good luck!
PS: Why little endian? For the ease of the implementation: it allows to use push_back when adding digits and iteration while implementing the operations will start from the first piece instead of the last piece in the array.

Mod of two large numbers in C++

I have a class named LargeNum, which stores large numbers by array such as digit[]. Because int is not large enough to store it.
The base is 10000, so number '9876 8764 7263' is stored like:
digit[4] = {9876, 8764, 7263};
(the base can be changed into 10 or 100, like digit[12] = {9,8,7,6,8,7,6,4,7,2,6,3})
The problem is that I want to overload operator %, so than I can get the remainder of two large numbers. Overloading operator *, - between large numbers is finished by dealing with every digit of the large number. But I really don't how to do so with %. Like:
{1234,7890,1234} % {4567,0023}
Can anyone help me?
The pseudocode should be:
while digits_source > digits_base {
while first_digit_source > first_digit_base {
source -= base << (digits_source - digits_base)
}
second_digit_source += first_digit_source * LargeNum.base
first_digit_source = 0
digits_source--
}
while (source >= base) {
source -= base
}
return source
This should take advantage of your "digits" of the large number.
Edit: For simplicity, I am assuming that a single digit of you array can contain (numerically speaking) two digits. If it cannot, then the code would become quite tricky because you cannot do second_digit_source += first_digit_source * LargeNum.base
Edit:
Regarding an example operation (base = 10000)
{65,0000,0099} % {32,0001}
As 65 is > 32, then proceed to do:
65 - 32 = 33
0 - 1 = -1
Then we have {33, -1, 99} % {32, 1}. Proceed again
33 - 32 = 1
-1 - 1 = -2
We have {1, -2, 99} % {32, 1}. Because 32 > 1, the we join the two first digits of the source and we have {1*1000 - 2, 99} % {32, 1}. Now we can go into the simple while, simply by doing the minus operation. The while does a full comparison of source >= base because we cannot afford to have negative digits. However, during the first part of the algorithm we can because we are guaranteeing that the combination of the two first digits will be positive.

Recursion solution for a number raised to an exponent

Hey I have a problem were I have to solve x^n in a number of ways. One of them involves using a recursion formula and its giving me a hard time. So one of the ways I used recursion for x^n for n>=0
int power2(int base, int power){
if (power == 0)
return 1;
else if ( power == 1)
return base;
else
return (base * power2(base, power - 1));
}
this makes sense to me So when i set X = 2 and N = 4, it is decreasing the power, which is acting as a counter, and doing 2x2 power raised to 3, 4*2, power raised to 2, 8 *2 = 16. Than the power is raised to 1, and I have a base case were if the power is raised to 1 it just returns base. However for my next one I have to solve it using three formulas.
x0 = 1
xn if n is even = [xn/2]2
xn if n is odd = x * [xn/2]2
So what I have so far is
int power3(int base, int power){
if(power == 0){
return 1;
}
else if ( power == 1)
return base;
// if power is even
if (power % 2 == 0){
return base*(power3(base,(power/2)));
}
// if power is odd
else{
return 0;
}
}
So im just trying to get even numbers to work first, and when I set x=2 and n=4 it returns 8. Which makes sense to me, since when the power is 4/2 will only loop twice for being >1. So i really am trying to figure out a way to get this to loop one more time while staying true to the formula I was given.and when I added the odd base case now the program will work up untill n^5 but n^6 returns 32
You got a little problem with the interpretation of the formula.
x^n if n is even = [x^n/2]2 doesn't mean:
base*(power3(base,(power/2))) //meaning x * [x^n/2]
rather you'd have
(power3(base,(power/2))) * 2
looking at your formula again it isn't correct even and should be x^n if n is even = [x^n/2]^2
so as code:
(power3(base,(power/2))) * (power3(base,(power/2)))
or:
(power3(base * base,(power/2)))
Your whole function should probably be like this:
int power3(int base, int power){
if(power == 0){
return 1;
}
else if ( power == 1) // you don't really need this case,
return base; // power == 0 is enough as base case
// if power is even
if (power % 2 == 0){
return (power3(base * base,(power/2)));
}
// if power is odd
else{
return base * (power3(base * base,(power/2)));
}
}
Ok, since you seem to still be confused with the odd powers.
Your power variable is int so you get integer division meaning 3/2 = 1 instead of 1.5 (everything behind the decimal point gets truncated).
Now lets look at the odd case in the function:
return base * (power3(base * base,(power/2)));
lets assume base == 4 and power == 5
return 4 * (power3(4 * 4,(5/2))); // 5/2 evaluates to 2
is the same as saying return 4 * (power3(4, 5 - 1))
and then having return (power3(4 * 4, 4 /2)) since we now got an even case.
We basically just do these 2 steps as 1. I think my explanation sounds a bit weird but hope it helps.

Fastest way of computing the power that a "power of 2" number used?

What would be the quickest way to find the power of 2, that a certain number (that is a power of two) used?
I'm not very skilled at mathematics, so I'm not sure how best to describe it. But the function would look similar to x = 2^y where y is the output, and x is the input. Here's a truth table of what it'd look like if that helps explain it.
0 = f(1)
1 = f(2)
2 = f(4)
3 = f(8)
...
8 = f(256)
9 = f(512)
I've made a function that does this, but I fear it's not very efficient (or elegant for that matter). Would there be a simpler and more efficient way of doing this? I'm using this to compute what area of a texture is used to buffer how drawing is done, so it's called at least once for every drawn object. Here's the function I've made so far:
uint32 getThePowerOfTwo(uint32 value){
for(uint32 n = 0; n < 32; ++n){
if(value <= (1 << n)){
return n;
}
}
return 32; // should never be called
}
Building on woolstar's answer - I wonder if a binary search of a lookup table would be slightly faster? (and much nicer looking)...
int getThePowerOfTwo(int value) {
static constexpr int twos[] = {
1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7,
1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15,
1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23,
1<<24, 1<<25, 1<<26, 1<<27, 1<<28, 1<<29, 1<<30, 1<<31
};
return std::lower_bound(std::begin(twos), std::end(twos), value) - std::begin(twos);
}
This operation is sufficiently popular for processor vendors to come up with hardware support for it. Check out find first set. Compiler vendors offer specific functions for this, unfortunately there appears to be no standard how to name it. So if you need maximum performance you have to create compiler-dependent code:
# ifdef __GNUC__
return __builtin_ffs( x ) - 1; // GCC
#endif
#ifdef _MSC_VER
return CHAR_BIT * sizeof(x)-__lzcnt( x ); // Visual studio
#endif
If input value is only 2^n where n - integer, optimal way to find n is to use hash table with perfect hash function. In that case hash function for 32 unsigned integer could be defined as value % 37
template < size_t _Div >
std::array < uint8_t, _Div > build_hash()
{
std::array < uint8_t, _Div > hash_;
std::fill(hash_.begin(), hash_.end(), std::numeric_limits<uint8_t>::max());
for (size_t index_ = 0; index_ < 32; ++index_)
hash_[(1 << index_) % _Div] = index_;
return hash_;
}
uint8_t hash_log2(uint32_t value_)
{
static const std::array < uint8_t, 37 > hash_ = build_hash<37> ();
return hash_[value_%37];
}
Check
int main()
{
for (size_t index_ = 0; index_ < 32; ++index_)
assert(hash_log2(1 << index_) == index_);
}
Your version is just fine, but as you surmised, its O(n) which means it takes one step through the loop for every bit. You can do better. To take it to the next step, try doing the equivalent of a divide and conquer:
unsigned int log2(unsigned int value)
{
unsigned int val = 0 ;
unsigned int mask= 0xffff0000 ;
unsigned int step= 16 ;
while ( value )
{
if ( value & mask ) { val += step ; value &= ~ mask ; }
step /= 2 ;
if ( step ) { mask >>= step ; } else { mask >>= 1 ; }
}
return val ;
}
Since we're just hunting for the highest bit, we start out asking if any bits are on in the upper half of the word. If there are, we can throw away all the lower bits, else we just narrow the search down.
Since the question was marked C++, here's a version using templates that tries to figure out the initial mask & step:
template <typename T>
T log2(T val)
{
T result = 0 ;
T step= ( 4 * sizeof( T ) ) ; // half the number of bits
T mask= ~ 0L - ( ( 1L << ( 4 * sizeof( T )) ) -1 ) ;
while ( val && step )
{
if ( val & mask ) { result += step ; val >>= step ; }
mask >>= ( step + 1) / 2 ;
step /= 2 ;
}
return result ;
}
While performance of either version is going to be a blip on a modern x86 architecture, this has come up for me in embedded solutions, and in the last case where I was solving a bit search very similar to this, even the O(log N) was too slow for the interrupt and we had to use a combo of divide and conquer plus table lookup to squeeze the last few cycles out.
If you KNOW that it is indeed a power of two (which is easy enough to verify),
Try the variant below.
Full description here: http://sree.kotay.com/2007/04/shift-registers-and-de-bruijn-sequences_10.html
//table
static const int8 xs_KotayBits[32] = {
0, 1, 2, 16, 3, 6, 17, 21,
14, 4, 7, 9, 18, 11, 22, 26,
31, 15, 5, 20, 13, 8, 10, 25,
30, 19, 12, 24, 29, 23, 28, 27
};
//only works for powers of 2 inputs
static inline int32 xs_ILogPow2 (int32 v){
assert (v && (v&(v-1)==0));
//constant is binary 10 01010 11010 00110 01110 11111
return xs_KotayBits[(uint32(v)*uint32( 0x04ad19df ))>>27];
}