How to fix my numberOfDigits function - performance

Came across some code where the number of digits was being determined by casting the number to a string then using a len().
Function numOfDigits_len(n As Long) As Long
numOfDigits_len = Len(Str(n)) - 1
End Function
Now although this works I knew it would be slow compared to any method that didn't use strings, so I wrote one that uses log().
Function numOfDigits_log(n As Long) As Long
numOfDigits_log = Int(Log(n) / Log(10)) + 1
End Function
Cut run time by 1/2 which was great but there was something weird happening in a specific case.
n numOfDigits_log(n)
===== ====================
999 3
1000 3
1001 4
It would not handle 1000 properly. I figured it is because of floating point and rounding issues.
Function numOfDigits_loop(ByVal n As Long) As Long
Do Until n = 0
n = n \ 10
numOfDigits_loop = numOfDigits_loop + 1
Loop
End Function
Wrote this which turned out to be ~10% slower as numbers got larger than 10^6 and seems to become slowly larger as n gets bigger. Which is fine if I was being pragmatic but I would like to find something more ideal.
Now my question is, is there a way to use the log() method accurately. I could do something like
Function numOfDigits_log(n As Long) As Long
numOfDigits_log = Int(Log(n) / Log(10) + 0.000000001) + 1
End Function
But it seems very "hacky". Is there a nicer way that's faster or as fast as the log() method?
Note: I realize this kind of optimization is pointless in a lot of cases but now that I've come across this I would like to "fix" it

I've answered this before, but I couldn't find it, so here's the basics:
int i = ... some number >= 0 ...
int n = 1;
if (i >= 100000000){i /= 100000000; n += 8;}
if (i >= 10000){i /= 10000; n += 4;}
if (i >= 100){i /= 100; n += 2;}
if (i >= 10){i /= 10; n += 1;}
That's in C, but you get the idea.

A while loop guarantees correctness, i.e. it doesn't use any floating point calculations
int numDigits = 0;
while(num != 0) {
num /= 10;
numDigits++;
}
You can also speed this up by using a larger divisor
int numDigits = 0;
if(num >= 100000 || num <= -100000) {
int prevNum;
while(num != 0) {
prevNum = num;
num /= 100000;
numDigits += 5;
}
num = prevNum;
numDigits -= 5;
}
while(num != 0) {
num /= 10;
numDigits++;
}

You'll love this.
We live in a base 10 number system! That means all you have to do is ROUND UP.
the length of some number ALWAYS = ceiling (log n). So for instance: 7456412 (a 7-digit number). Log (7456412) = 6.8...round up and you have 7. log (9999) = 3.9999. Round up and it's 4.
The special case is when you DON'T have to round, or when you have some power of 10. For instance: log(1000) = 3. if you can detect when you have a power of 10, add one to the log result and you win!
the way you could do this detection is something like
double log10;
int clog10;
int length;
log10 = (Log(n) / Log(10)); // can also use a private static final long hardcoded for Log(10)
clog10 = ceiling(log10);
if (Int(log10) == clog10)
length = clog10 + 1;
else
length = clog10;

Related

Processing 3.3.7 Carmichael function

So I am trying to make a carmichael function in processing for some RSA encryption stuff I am playing with, but the modulo function seems to give many wrong answers.
here is my code:
int carmichael(int n) {
int checkIndex = 0;
int m = 1;
ArrayList<Integer> coprimes = findCoprimesLessThan(n);
println(coprimes);
for(m = 1; m < 50; m++){
for(checkIndex = 0; checkIndex < coprimes.size(); checkIndex++){
int a = coprimes.get(checkIndex);
float mod = pow(a, m) % n;
println(a, m, n, mod, pow(a, m), pow(a, m) % n);
if (mod == 1) {
continue;
}
if (mod != 1){
break;
}
return m;
}
}
return 1;
}
And for an input of say, 31, it loops forever (I have it stop at 100 just for this reason so it just outputs 1 if it goes through all 100 and doesn't find anything) when it should give 30. I believe I have narrowed it down to the modulo operation not working on large numbers as that seems to be the problem, for example:
when a = 3, m = 30, and n = 31, my println statement gives this:
3 30 31 18.0 2.05891136E14 18.0
and all of that is correct except the modulo, it gives 18.0 when it should be 1.0. I am unsure of anyway to get around this as even doing a "manual modulus" like this:
while(mod >= n){
mod-= n;
}
results in the exact same problem. All research I have done into the carmichael function has led me to either confusion or here which was no help.
My guess is you're hitting a limit of float precision.
Float values can only track a certain amount of precision. Try running this example program:
float one = 123456789;
float two = one + 1;
println(one == two);
You would expect this to print false, but if you run it, you'll see that it prints true instead. This is because we're outside the bounds of precision.
To get around this, you could upgrade to the double type. Double values have the same problem, but at a higher level of precision.
double one = 123456789;
double two = one + 1;
println(one == two);
Getting back to your code, by default Processing treats everything as a float value. This is fine for most cases, but if you need lots of precision then you're better off switching to double value.
int a = 3;
int m = 30;
int n = 31;
double p = Math.pow(a, m);
println(p);
double mod = p % n;
println(mod);
Note that I'm using Math.pow() instead of pow(). The Math.pow() function comes from Java and takes and returns double values instead of float values.
(By the way, this is the type of example program I was talking about in the comments.)

Iterative Factorial Implementation

I found multiple iterative solutions in the net for defining the factorial of n. They look something like this:
int Factorial(int number)
{
int factorial = 1;
for (int i = 1; i <= number; i++)
factorial *= i;
return factorial;
}
Doesn't Factorial(0) = 1 and Factorial(1) = 1? Therefore, the counter variable inside the for loop should start with 2 since everything below it will yield 1.
for (int i = 2; i <= number; i++)
factorial *= i;
Is there some reason why they used 1 as the starting number for the counter?
It doesn't matter - either 1 or 2 will work, as multiplying by 1 does nothing. However, most loops start with 0 or 1, and this just follows the pattern. Also, the definition of factorial is often stated as the product of all positive integers up to n, so this includes one. Essentially, 1 is, aesthetically, a better starting point.
For iterative functions in python:
def iterative_factorial(n):
x = 1
for i in range(2,n+1):
x *= i
return x
print(iterative_factorial(n))

convert decimal to base x

I'm trying to solve a problem which asks to find all squares of 1 <= N <= 300 that are palindromic when expressed in base B. I've got my solution however, it's way too slow and what is slowing it down is my solution to converting a number to base B.
long around(long n)
{
long around = 0;
while (n > 0){
around = around * 10 + (n % 10);
n = n / 10;
}
return around;
}
long convert(int n, int b)
{
long x = 0;
while (true){
x = x * 10 + (n % b);
if (n == 1)
break;
n = n / b;
}
return around(x);
}
Please recommend any faster solutions to converting decimal to base B or give any tips to improve my current solutions performance.
The problem is your convert function, which runs into an infinite loop. You are only breaking when n == 1, but what if it never becomes 1?
Consider n = 4 and b = 5. Then 4 / 5 will be 0. Once n is zero, it will always be zero, and never 1.
You should break out of the loop when n < b.

Division without using '/'

Can anyone tell me an efficient approach to perform the division operation without using '/'. I can calculate the integer value in log(n) steps using a method similar to binary search.
115/3
57 * 3 > 115
28 * 3 < 115
47 * 3 > 115
.
.
.
38 * 3 is quotient value .....
But is there any other more efficient method?
The typical way is to shift and subtract. This is basically pretty similar to long division as we learned it in school. The big difference is that in decimal division you need to estimate the next digit of the result. In binary, that's trivial. The next digit is always either 0 or 1. If the (left-shifted) divisor is less than or equal to the current dividend value, you subtract it, and the current bit of the result is a 1. If it's greater, then the current bit of the result is a 0. Code looks like this:
unsigned divide(unsigned dividend, unsigned divisor) {
unsigned denom=divisor;
unsigned current = 1;
unsigned answer=0;
if ( denom > dividend)
return 0;
if ( denom == dividend)
return 1;
while (denom <= dividend) {
denom <<= 1;
current <<= 1;
}
denom >>= 1;
current >>= 1;
while (current!=0) {
if ( dividend >= denom) {
dividend -= denom;
answer |= current;
}
current >>= 1;
denom >>= 1;
}
return answer;
}
This works pretty much like when we do long division by hand. For example, let's consider 972/5. In decimal long division, we do something like this:
____
5)972
Then we figure each digit individually. 5 goes into 9 once, so we write down a 1 in that digit of the answer, and subtract 1*5 from (that digit) of the dividend, then "bring down" the next digit of the dividend:
1
----
5)972
5
---
47
We continue doing the same until we've filled in all the digits:
194
----
5)972
5
---
47
45
---
22
20
---
2
So, our answer is 194 remainder 2.
Now let's consider the same thing, but in binary. 972 in binary is 11 1100 1100, and 5 is 101. Now there is one fundamental difference between doing the division in binary vs. decimal: in decimal a particular digit could be anything from 0 to 9, so we had to multiply to find the intermediate result we were going to subtract from the dividend. In binary the digit is only ever going to be a 0 or a 1. We never need to multiply because we would only ever multiply by 0 or 1 (which we normally handle in an if statement--either we subtract or we don't).
-----------
101)1111001100
So, our first step is to figure out which will be the first digit in the result. We do that by comparing 101 to 1111001100, and shifting it left until it's greater. That gives us:
|
1111001100
10100000000
As we do that shifting, we count the number of places we've shifted so we know which digit of the result we're filling in at any given time. I've shown that with the vertical bar above. Then we shift the intermediate result right one place, and shift the vertical bar right with it to signify where we're doing to fill in a result digit:
|
1111001100
1010000000
From there we check if the shifted divisor is less than the dividend. If it is, we fill in a 1 in the proper place in the answer, and subtract the shifted divisor from the intermediate result [and to help keep columns straight, I'm going to insert some spaces]:
1
-----------------------------
101)1 1 1 1 0 0 1 1 0 0
1 0 1 0 0 0 0 0 0 0
----------------------------
1 0 1
We continue the same way, filling in digits of the result, and subtracting the shifted divisor from the intermediate result until we've filled in all the digits. In a further attempt at helping keep things straight, I'm going to write in each digit of the result at the far right next to the subtrahend:
1 1 0 0 0 0 1 0
-----------------------------
101)1 1 1 1 0 0 1 1 0 0
1 0 1 1
-----------------------------
1 0 1
1 0 1 1
-----------------------------
0 0 0 0
--------------------------
0 0 0 0
-------------------------
0 0 1 0
-------------------------
0 1 1 0
-------------------------
1 1 0
1 0 1 1
------------------------
0 1 0 0
So, we get a result of 11000010, remainder 10. Converting those to decimal, we get the expected 194 and 2 respectively.
Let's consider how that relates to the code above. We start by shifting the divisor left until it's greater than the dividend. We then repeatedly shift it right and for each right shift check whether that value is less than the intermediate we got after the last subtraction. If it's less, we subtract again and fill in a 1 for that digit in our result. If it's greater, we "subtract 0" (don't do anything) and fill in a '0' for that digit in the result (which, again, doesn't require us to do anything, since those digits are already set to 0's).
When we've filled in all the digits, that's our result, and any amount left that we haven't subtracted yet is our remainder.
Some have asked why I used |= instead of += in the code. I hope this helps explain why. Although in this case they produce the same result, I don't think of adding each digit to the existing partial answer. Rather, I think of it that spot in the answer as being empty, and the or just fills it in.
Options:
Code your own division algorithm based on the long division algorithm you learned in grade school.
Take the -1 power of the denominator, and multiply onto the numerator
Take the logs of the numerator and denominator, subtract, and then raise the base of the log to that same power
Simple Python implementation using basic high school math. A denominator is simply a number to the power of negative 1.
def divide(a, b):
return a * b ** -1
Following is the Java code for dividing number without using division operator.
private static int binaryDivide(int dividend, int divisor) {
int current = 1;
int denom = divisor;
// This step is required to find the biggest current number which can be
// divided with the number safely.
while (denom <= dividend) {
current <<= 1;
denom <<= 1;
}
// Since we may have increased the denomitor more than dividend
// thus we need to go back one shift, and same would apply for current.
denom >>= 1;
current >>= 1;
int answer = 0;
// Now deal with the smaller number.
while (current != 0) {
if (dividend >= denom) {
dividend -= denom;
answer |= current;
}
current >>= 1;
denom >>= 1;
}
return answer;
}
(This is a solution to the problem where you are not allowed to use multiplication either).
I like this solution: https://stackoverflow.com/a/5387432/1008519, but I find it somewhat hard to reason about (especially the |-part). This solution makes a little more sense in my head:
var divide = function (dividend, divisor) {
// Handle 0 divisor
if (divisor === 0) {
return NaN;
}
// Handle negative numbers
var isNegative = false;
if (dividend < 0) {
// Change sign
dividend = ~dividend+1;
isNegative = !isNegative;
}
if (divisor < 0) {
// Change sign
divisor = ~divisor+1;
isNegative = !isNegative;
}
/**
* Main algorithm
*/
var result = 1;
var denominator = divisor;
// Double denominator value with bitwise shift until bigger than dividend
while (dividend > denominator) {
denominator <<= 1;
result <<= 1;
}
// Subtract divisor value until denominator is smaller than dividend
while (denominator > dividend) {
denominator -= divisor;
result -= 1;
}
// If one of dividend or divisor was negative, change sign of result
if (isNegative) {
result = ~result+1;
}
return result;
}
Initialize the result to 1 (since we are going to double our denominator until it is bigger than the dividend)
Double the denominator (with bitwise shifts) until it is bigger than the dividend
Since we know our denominator is bigger than our dividend, we can subtract the divisor until it is less than the dividend
Return the recorded actions it took to get as close to the denominator as possible using the divisor
Here are some test runs:
console.log(divide(-16, 3)); // -5
console.log(divide(16, 3)); // 5
console.log(divide(16, 33)); // 0
console.log(divide(16, 0)); // NaN
console.log(divide(384, 15)); // 25
Here is a gist handling both the 0 divisor case and negative dividend and/or divisor: https://gist.github.com/mlunoe/e34f14cff4d5c57dd90a5626266c4130
Since the OP said it's an interview question, I think the interviewer wants to see the following things in addition to your coding skills. (Suppose you are using Java)
How to deal with negative numbers? It's common to convert both the dividend and the divisor to positive numbers. However, you may forget that Math.abs(Integer.MIN_VALUE) is still Integer.MIN_VALUE. Therefore, when the dividend is Integer.MIN_VALUE, you should calculate it separately.
What's the result of "Integer.MIN_VALUE/-1"? There is no such value in Integer. You should discuss it with the interviewer. You can throw an exception for this condition.
Here is the Java code for this question and you can validate it leetcode:divide two integers:
public int divide(int dividend, int divisor) {
if(divisor == 0)
throw new Exception("Zero as divisor!");
int a = Math.abs(dividend);
int b = Math.abs(divisor);
boolean isPos = true;
if(dividend < 0) isPos = !isPos;
if(divisor < 0) isPos = !isPos;
if(divisor == Integer.MIN_VALUE){
if(dividend == Integer.MIN_VALUE) return 1;
else return 0;
}
if(dividend == Integer.MIN_VALUE) {
if(divisor == -1){
// the result is out of Integer's range.
throw new Exception("Invalid result.");
} else {
// Because Math.abs(Integer.MIN_VALUE) = Integer.MIN_VALUE
// we avoid it by adding a positive divisor to Integer.MIN_VALUE
// here I combined two cases: divisor > 0 and divisor < 0
return divide((dividend + b), divisor) - divisor/b;
}
}
int res = 0;
int product = b;
while(a >= b){
int multiplier = 1;
while(a - product >= product){
product = product << 1;// "product << 1" is actually "product * 2"
multiplier = multiplier << 1;
}
res += multiplier;
a -= product;
product = b;
}
return isPos?res:-res;
}
The main concept :
Let's say we are calc 20/4, so
4*(1+1) = 8 *(1+1) = 16 *(1+1) == 32 (which is bigger) X
so go back to 16 and try 16*(1+0.5) == 24 (bigger) X
so go back to 16 and try 16*(1+0.25) == 20
The code:
float product=1,multiplier=2,a=1;
int steps=0;
void divCore(float number, float divideBy,float lastDivison)
{
steps++;
//epsilon check e.g (10/3) will never ends
if(number - divideBy < 0.01)
return;
else
{
lastDivison = divideBy;
divideBy *= multiplier;
if(number >= divideBy)
{
product *= multiplier;
divCore(number,divideBy,lastDivison);
}
else
{
a *= 0.5;
multiplier = 1 + a;
divCore(number,lastDivison,lastDivison);
}
}
}
float Divide(float numerator, float denominator)
{
//init data
int neg=(numerator<0)?-1:1;
neg*=(denominator<0)?-1:1;
product = 1;
multiplier = 2;
a = 1;
steps =0;
divCore(abs(numerator),abs(denominator),0);
return product*neg;
}
Division of two numbers without using /
int div(int a,int b){
if(b == 0)
return -1; //undefined
else if (b == 1)
return a;
else if(b > 1){
int count = 0;
for(int i=b;i<=a;i+=b){
count++;
}
}
return count;
}
Here is a simple divide method for ints without using a '/' operator:-
public static int divide(int numerator, int denominator) throws Exception {
int q = 0;
boolean isNumPos = (numerator >= 0) ? true : false;
boolean isDenPos = (denominator >= 0) ? true : false;
if (denominator == 0) throw new Exception("Divide by 0: not an integer result");
numerator = Math.abs(numerator);
denominator = Math.abs(denominator);
while (denominator <= numerator) {
numerator -= denominator;
q++;
}
return (isNumPos ^ isDenPos) ? -q : q;
}
Here's one in JavaScript:
function divideWithoutDivision(a, b, precision) {
precision = precision > 0 ? precision : 10
var result = 0
var decimalPosition = 1
var A = a*0.1
var howManyTimes = 0
while (precision--) {
A = A * 10
howManyTimes = 0
while (A >= b) {
A = A - b
howManyTimes += 1
}
result = result + howManyTimes*decimalPosition
decimalPosition = decimalPosition * 0.1
}
return result
}
document.write('<br>20/3 = ', divideWithoutDivision(20, 3))
document.write('<br>10/3 = ', divideWithoutDivision(10, 3))
document.write('<br>10/4 = ', divideWithoutDivision(10, 4))
document.write('<br>17/14 = ', divideWithoutDivision(17, 14))
document.write('<br>23/4 = ', divideWithoutDivision(23, 4))
It could be further improved by rounding after the last decimal place of the precision.
Perhaps you can devise a way to do it using sequences of >> (bit shifts) with other bitwise operators. There's an example in psuedo-code in the Wikipedia: Bitwise Operator article.
Well, if this is only integer/integer = int type division, it's pretty easy to get the integer part of x / n = int.dec by adding n+n+n+n until n is greater than x, then subtracting one from your 'n' count.
To get int/int = real without using *, /, %, or other math functions, you could do several things. You could return the remainder as a rational, for example. That has the advantage of being exact. You could also use string modification to turn your r into r0... (you pick the precision) and then repeat the same addition trick, then concatenate the results.
And of course, you could try having fun with bit shifting.
I don't know if this is so much a 'silly trick' as it is a test of how well you can use simple things (addition, subtraction) to build a complex thing (division). This is a skill that your potential employer might need, because there isn't an operator for everything. A question like this should (theoretically) weed out people who can't design algorithms from people who can.
I do think it's a problem that the answer is so readily available on the internet, but that's an implementation issue.
This is the function that solved my problem:
func printRemainderAndQuotient(numerator: Int,divisor: Int) {
var multiplier = 0
var differene = numerator - divisor
var dynamicNumber = 0
if divisor == 0 {
print("invalid divisor")
return
}
if divisor == numerator {
print("quotient : " + "1")
print("remainder : " + "0")
return
}
while differene >= divisor {
multiplier = multiplier + 1
dynamicNumber = divisor * multiplier
differene = numerator - dynamicNumber
}
print("quotient : " + "\(multiplier)")
print("remainder : " + "\(differene)")
}
If you take the division as a subtraction, what it basically is, you could use a method "decrement" what allows you to not use any operator at all, except for ~ at the end, to invert the result later into a positive integer or any other value.
private static int decrement(int i) {
System.out.println("Value of decrement : ");
System.out.println(i);
return i - 1;
}
private static int divide(int n, int d) {
assert n > 0 && d > 0;
int counter = 0;
while (n >= d) {
for (int i = d; i > 0; i = decrement(i)) {
n = decrement(n);
}
counter = decrement(counter);
}
counter =~decrement(counter);
System.out.println(counter);
return counter;
}
well, let's see... x/y = e^(ln(x)-ln(y))
private int divideBy2(int number){
int count = 1;
while(count<=number){
if(count*2==number){
return count;
}
count++;
}
return count;
}

Write a function to divide a number by 3 without using /, % and * operators. itoa() available?

I tried to solve it myself but I could not get any clue.
Please help me to solve this.
Are you supposed to use itoa() for this assignment? Because then you could use that to convert to a base 3 string, drop the last character, and then restore back to base 10.
Using the mathematical relation:
1/3 == Sum[1/2^(2n), {n, 1, Infinity}]
We have
int div3 (int x) {
int64_t blown_up_x = x;
for (int power = 1; power < 32; power += 2)
blown_up_x += ((int64_t)x) << power;
return (int)(blown_up_x >> 33);
}
If you can only use 32-bit integers,
int div3 (int x) {
int two_third = 0, four_third = 0;
for (int power = 0; power < 31; power += 2) {
four_third += x >> power;
two_third += x >> (power + 1);
}
return (four_third - two_third) >> 2;
}
The 4/3 - 2/3 treatment is used because x >> 1 is floor(x/2) instead of round(x/2).
EDIT: Oops, I misread the title's question. Multiply operator is forbidden as well.
Anyway, I believe it's good not to delete this answer for those who didn't know about dividing by non power of two constants.
The solution is to multiply by a magic number and then to extract the 32 leftmost bits:
divide by 3 is equivalent to multiply by 1431655766 and then to shift by 32, in C:
int divideBy3(int n)
{
return (n * 1431655766) >> 32;
}
See Hacker's Delight Magic number calculator.
x/3 = e^(ln(x) - ln(3))
Here's a solution implemented in C++:
#include <iostream>
int letUserEnterANumber()
{
int numberEnteredByUser;
std::cin >> numberEnteredByUser;
return numberEnteredByUser;
}
int divideByThree(int x)
{
std::cout << "What is " << x << " divided by 3?" << std::endl;
int answer = 0;
while ( answer + answer + answer != x )
{
answer = letUserEnterANumber();
}
}
;-)
if(number<0){ // Edited after comments
number = -(number);
}
quotient = 0;
while (number-3 >= 0){ //Edited after comments..
number = number-3;
quotient++;
}//after loop exits value in number will give you reminder
EDIT: Tested and working perfectly fine :(
Hope this helped. :-)
long divByThree(int x)
{
char buf[100];
itoa(x, buf, 3);
buf[ strlen(buf) - 1] = 0;
char* tmp;
long res = strtol(buf, &tmp, 3);
return res;
}
Sounds like homework :)
I image you can write a function which iteratively divides a number. E.g. you can model what you do with a pen and a piece of paper to divide numbers. Or you can use shift operators and + to figure out if your intermediate results is too small/big and iteratively apply corrections. I'm not going to write down the code though ...
unsigned int div3(unsigned int m) {
unsigned long long n = m;
n += n << 2;
n += n << 4;
n += n << 8;
n += n << 16;
return (n+m) >> 32;
}
int divideby3(int n)
{
int x=0;
if(n<3) { return 0; }
while(n>=3)
{
n=n-3;
x++;
}
return x;
}
you can use a property from the numbers: A number is divisible by 3 if its sum is divisible by3.
Take the individual digits from itoa() and then use switch function for them recursively with additions and itoa()
Hope this helps
This is very easy, so easy I'm only going to hint at the answer --
Basic boolean logic gates (and,or,not,xor,...) don't do division. Despite this handicap CPUs can do division. Your solution is obvious: find a reference which tells you how to build a divisor with boolean logic and write some code to implement that.
How about this, in some kind of Python like pseudo-code. It divides the answer into an integer part and a fraction part. If you want to convert it to a floating point representation then I am not sure of the best way to do that.
x = <a number>
total = x
intpart = 0
fracpart = 0
% Find the integer part
while total >= 3
total = total - 3
intpart = intpart + 1
% Fraction is what remains
fracpart = total
print "%d / 3 = %d + %d/3" % (x, intpart, fracpart)
Note that this will not work for negative numbers. To fix that you need to modify the algorithm:
total = abs(x)
is_neg = abs(x) != x
....
if is_neg
print "%d / 3 = -(%d + %d/3)" % (x, intpart, fracpart)
for positive integer division
result = 0
while (result + result + result < input)
result +=1
return result
Convert 1/3 into binary
so 1/3=0.01010101010101010101010101
and then just "multiply" whit this number using shifts and sum
There is a solution posted on http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3776384&page=1&extra=#pid22323016
int DividedBy3(int A) {
int p = 0;
for (int i = 2; i <= 32; i += 2)
p += A << i;
return (-p);
}
Please say something about that, thanks:)
Here's a O(log(n)) way to do it with no bit shifting, so it can handle numbers up-to and including your biggest register size.
(c-style code)
long long unsigned Div3 (long long unsigned n)
{
// base case:
if (n < 6)
return (n >= 3);
long long unsigned division = 0;
long long unsigned remainder = 0;
// Used for results for only a single power of 2
// Initialise for 2^0
long long unsigned tmp_div = 0;
long long unsigned tmp_rem = 1;
for (long long unsigned pow_2 = 1; pow_2 && (pow_2 <= n); pow_2 += pow_2)
{
if (n & pow_2)
{
division += tmp_div;
remainder += tmp_rem;
}
if (tmp_rem == 1)
{
tmp_div += tmp_div;
tmp_rem = 2;
}
else
{
tmp_div += tmp_div + 1;
tmp_rem = 1;
}
}
return division + Div3(remainder);
}
It uses recursion, but note that the number drops exponentially in size at each iteration, so the time complexity (TC) is really:
O(TC) = O(log(n) + log(log(n)) + log(log(log(n))) + ... + z)
where z < 6.
Proof that it's O(log(n)):
We note that the number at each recursion strictly decreases (by at least 1):
So series = [log(log(n))] + [log(log(log(n)))] + [...] + [z]) has at most log(log(n)) sums.
implies:
series <= log(log(n))*log(log(n))
implies:
O(TC) = O(log(n) + log(log(n))*log(log(n)))
Now we note for n sufficiently large:
sqrt(x) > log(x)
iff:
x/sqrt(x) > log(x)
implies:
x/log(x) > log(x)
iff:
x > log(x)*log(x)
So O(x) > O(log(x)*log(x))
Now let x = log(n)
implies:
O(log(n)) > O(log(log(n))*log(log(n)))
and given:
O(TC) = O(log(n) + log(log(n))*log(log(n)))
implies:
O(TC) = O(log(n))
Slow and naive, but it should work, if an exact divisor exists. Addition is allowed, right?
for number from 1 to input
if number == input+input+input
return number
Extending it for fractional divisors is left as an exercise to the reader.
Basically test for +1 and +2 I think...

Resources