Help with mathematical side of programming? I am a student trying to learn programming on my own, getting help from online sources and people like you. I found an exercise online to create a small program 
The program should read the numbers a and b and count how many numbers between a and b are divisible by either 2, 3 or 5.
If the user types the number 5 and then 8.... it would look at all the numbers in between - 5,6,7,8 and check if any of them are devisable by either 2,3 or 5. And since the numbers 5,6,8 are it would return the number 3 to the user....
Now the problem is that this program only works for small numbers, but when I try to input numbers such as 123456789012345678 and 876543210987654321... it doesn't run at all.Well it runs but the time it takes the computer to check each number is way too long..so it would take years to finish.
Now I am stuck... I want it to work on bigger numbers as well...such as 
 a=123456789012345678 b=876543210987654321  where it will give me the answer  552263376115226339 
Since this is more of a problem for mathematicians ..something to change the algorithm of this program I am turning to you guys for your guidance and help.
There must be a quicker way ...something that can modify the code so it finishes in the matter of seconds not hours. Something that will speed up the process of checking if the numbers are divisible...
Could you please help me with that? Because I am completely lost on what to do. Thank you for your help in advance !
 A: The key insight you need is that $n$ is divisible by 2, 3, or 5 exactly if $n+30$ is. So the pattern of "do I want to count this or not" repeats every 30 steps. (30 is the least common multiple of 2, 3, and 5).
Every set of 30 consecutive integers contains exactly 22 numbers that are divisible by 2, 3, or 5 (if I've counted correctly; better check it yourself).
So you can save a lot of time by first computing how many full sets of 30 numbers there are in your interval, and then just check the few remaining ones one by one.
A: I'll suggest a progressive approach to modifying code:
long f(long a, long b) {
    long count = 0;
    for (long c = a; c <= b; c++) {
        if (c % 2 == 0 || c % 3 == 0 || c % 5 == 0) {
            count++;
        }
    }
    return count;
}

Notice that this is the same as:
long g(long b) {
    long count = 0;
    for (long c = 1; c <= b; c++) {
        if (c % 2 == 0 || c % 3 == 0 || c % 5 == 0) {
            count++;
        }
    }
    return count;
}

long f(long a, long b) {
    return g(b) - g(a - 1);
}

Now you only have to consider improving $g$, which is much easier to reason about.
Consider a function $h$:
long h(long b, long d) {
    long count = 0;
    for (long c = 1; c <= b; c++) {
        if (c % d == 0) {
            count++;
        }
    }
    return count;
}

Is it true that $g(b) = h(b, 2) + h(b, 3) + h(b, 5)$ ?  It is almost true...but consider when $c \text{ % } 6 == 0$.  It will be counted in both $h(b, 2)$ and $h(b, 3)$, in other words, you counted it twice.
So a closer answer is $g(b) \approx h(b, 2) + h(b, 3) + h(b, 5) - h(b, 2*3) - h(b, 2*5) - h(b, 3*5)$.  But what about when $c \text{ % } (2*3*5) == 0$ ?  Those $c$ values get overadded twice, but subtracted three times.  So the correct relation between $g$ and $h$ is:
$$g(b) = h(b, 2) + h(b, 3) + h(b, 5) - \underbrace{h(b, 2*3) - h(b, 2*5) - h(b, 3*5)}_\text{fixing overcounts} + \underbrace{h(b, 2*3*5)}_\text{fixing over subtraction}$$
And finally, $h$ can be computed with just a single division, much faster than a for loop.  The technique we used to find the relation between $g$ and $h$ is The principle of Inclusion and Exclusion.

In response to the question update:
import java.util.Scanner;

public class Test {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        long a = sc.nextLong();
        long b = sc.nextLong();

        long end = f(a, b);
        System.out.println("Number is " + end);
    }

    public static long f(long a, long b) {
        long count = 0;
        long range = b - a;
        System.out.println("Range is" + "  " + range);
        long repeatingSet = (range / 30) * 22;
        System.out.println("Repeating set of 22 between 30 numbers is " + "  " + repeatingSet);
        long remainder = range % 30;
        System.out.println("Remainder is  " + remainder);
        for(long j = 0; j <= remainder; j++) {
            if (j % 2 == 0 || j % 3 == 0 || j % 5 == 0) {
                count++;
            }
        }
        long end = count + repeatingSet;
        return end;
    }
}

Your code isn't quite correct.  Test it with values like $a=20$ and $b=81$, or $a=20$ and $b=82$.
I think you might have misunderstood part of Mr. Henning Makholm's suggestion.  What he was suggesting to you is:
$$f(a, a+30) = 22$$
for any value of $a$ which you choose, which is correct.  However, if you were to check:
$$f(a, a+27)$$
you'll see that there are many different values this can have.  The problem with your code is that you start counting with $j=0$:
for (long j = 0;

Think of the problem this way.  Write your function $f$ like this (this is abstract, it wont actually compile):
public static long f(long a, long b) {
    long count = 0;
    for(long c = a; c < a + 30; c++) {
        if (c % 2 == 0 || c % 3 == 0 || c % 5 == 0) count++;
    }
    for(long c = a + 30; c < a + 60; c++) {
        if (c % 2 == 0 || c % 3 == 0 || c % 5 == 0) count++;
    }
    for(long c = a + 60; c < a + 90; c++) {
        if (c % 2 == 0 || c % 3 == 0 || c % 5 == 0) count++;
    }
    for(long c = a + 90; c < a + 120; c++) {
        if (c % 2 == 0 || c % 3 == 0 || c % 5 == 0) count++;
    }

    // etc

    for(long c = a + 30*k; c <= b; c++) {
        if (c % 2 == 0 || c % 3 == 0 || c % 5 == 0) count++;
    }

    return count;
}

The first $4$ for loops will increase the value of $\text{count}$ by $22$.  Now obviously //etc isn't a valid java command.   Would be nice if it was.  So what you want to do is replace the top set of for loops with:
public static long f(long a, long b) {
    long count = 0;
    int NumberOfForLoops = ??? ;
    count = count + 22*NumberOfForLoops;

    for(long c = a + 30*NumberOfForLoops; c <= b; c++) {
        if (c % 2 == 0 || c % 3 == 0 || c % 5 == 0) count++;
    }

    return count;
}

And this should give you the correct answer.  I'll leave figuring out what ??? should be to you, but if you want to check your answer, here it is:

 int NumberOfForLoops = (b - a) / 30;

// or you can use

 int NumberOfForLoops = (b - a + 1) / 30;

A: You can use a purely mathematical method, it's called inclusion-exclusion principle. You can calculate the amount of such numbers between $1$ and $a$; also $1$ and $b$ and then just substruct them. Let $A_a$, $B_a$ and $C_a$ be the set of numbers smaller than $a$ divisible by 2,3 and 5 respectivery. Simularly define $A_b$, $B_b$ and $C_b$.
It simple to notice that;
$$A_a = \left \lfloor {\frac a2} \right \rfloor \quad \quad B_a = \left \lfloor {\frac a3} \right \rfloor \quad \quad C_a = \left \lfloor {\frac a5} \right \rfloor$$
$$A_b = \left \lfloor {\frac b2} \right \rfloor \quad \quad B_b = \left \lfloor {\frac b3} \right \rfloor \quad \quad C_b = \left \lfloor {\frac b5} \right \rfloor$$
Then from the inclusion-exclusion principle we have:
$$\mid A_a \cup B_a \cup C_a\mid = \mid A_a \mid + \mid B_a \mid + \mid C_a \mid - \mid A_a \cap B_a \mid - \mid A_a \cap C_a \mid - \mid B_a \cap C_a \mid + \mid A_a \cap B_a \cap C_a \mid  $$
$$\mid A_b \cup B_b \cup C_b\mid = \mid A_b \mid + \mid B_b \mid + \mid C_b \mid - \mid A_b \cap B_b \mid - \mid A_b \cap C_b \mid - \mid B_b \cap C_b \mid + \mid A_b \cap B_b \cap C_v \mid  $$
Then simply the wanted number is:
$$\mid A_b \cup B_b \cup C_b\mid - \mid A_a \cup B_a \cup C_a\mid$$
A: I'm using the same approach as Stefan's answer, but hopefully in a slightly easier way.
First, let's consider just the numbers from 1 - 20:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
Now, if we count all of the numbers divisible by 2, we end up with $20 \div 2 = 10$ numbers:
1, 2 (1), 3, 4(1), 5, 6 (1), 7, 8 (1), 9, 10 (1) ... 19, 20 (1)
Note that the parentheses indicate how many times the number has been counted.
Performing something similar with $3$ and $5$, we obtain:
1, 2 (1), 3 (1), 4 (1), 5 (1), 6 (2), 7 (1), 8 (1), 9 (1), 10 (2) ... 19, 20 (2)
Do you see why $6$ and $10$ were counted twice? Once for the multiples of 2, and once for the multiples of 3 and/or 5. This is obviously a problem, so we subtract what we've double counted, namely numbers divisible by $GCF(2, 3) = 6$, $GCF(3, 5) = 15$ or $GCF(2, 5) = 10$.
So now, $6$ and $10$ are counted only once.
But we have yet another problem: if our numbers extended up to 30, then we would have failed to count 30. We counted it 3 times because it is divisible by 2, 3, and 5, but we subtracted 3 from its count because it is divisible by 6, 15, and 10. Which makes a total of 0 -- essentially, we've "over subtracted" numbers divisible by 30. So we need to add the number of numbers divisible by 30 back.
This is the inclusion-exclusion principle. Basically, in your case:
totalNumber = numbersDivisibleBy2 + numbersDivisibleBy3 + numbersDivisibleBy5
              - numbersDivisibleBy6 - numbersDivisibleBy15 - numbersDivisibleBy10
               + numbersDivisibleBy30

Or more generally:
total = primary - secondary + sharedByAll3

I don't know much java, but this would look like:
// If java does automatic flooring for numbers that don't divide evenly this will work
// Otherwise do 'Math.floor' or something on each one
long total = (n / 2)  + (n / 3) + (n / 5)
             - (n / 6) - (n / 10) - (n / 15)
             + (n / 30);

You can visualize this using a venn diagram with 3 circles, but unfortunately I don't have a good diagram that I can find.
