I have this issue where I need to square line in Pascal's triangle and when it comes to big numbers it only outputs 0
unsigned long sum_squared(const int line){
unsigned long long n = 2*line;
unsigned long long x1 = factorial(line);
unsigned long long k = x1*x1;
unsigned long long x = factorial(n)/(k);
return x;
}
unsigned long long factorial(unsigned long long n) {
if (n == 0){
return 1;
}
return n * factorial(n - 1);
}
I test it with:
printf("%lu\n", sum_squared(14));
The key word here is "outputs". You need the correct format specifier to output unsigned long long: %llu.
The maximum number should be 7219428434016265740 and it equals sum_squared(33)
The code tries to evaluate the sum using (directly) the formula
⎛ 2n ⎞ (2n)!
⎜ ⎟ = ―――――
⎝ n ⎠ n!·n!
As noted in the other answers and comments, this leads to overflow of the intermediate results.
Luckily, this expression can be simplified and evaluated safely (without overflowing 64-bit wide unsigned integers) up to the required value.
We can start dividing both the numerator and the denominator by n!
(2n)! (n+1)·(n+2)· ... ·(n+n) (n+1)·(n+2)· ... ·(2n-2)·(2n-1)·(2n)
――――― = ――――――――――――――――――――――― = ――――――――――――――――――――――――――――――――――――
n!·n! n! 1·2· ... ·(n-1)·n
Also note that the higher half terms in the denominator have the corresponding doubles in the numerator. Let's see a couple of examples
⎛ 8 ⎞ 8! 5·6·7·8 5·2·7·2
⎜ ⎟ = ――――― = ――――――― = ――――――― = 70
⎝ 4 ⎠ 4!·4! 1·2·3·4 1·2
⎛ 10 ⎞ 10! 6·7·8·9·10 2·7·2·9·2 70
⎜ ⎟ = ――――― = ―――――――――― = ――――――――― = 252 = ―― · 9 · 2
⎝ 5 ⎠ 5!·5! 1·2·3·4·5 1·2 5
⎛ 12 ⎞ 12! 7·8·9·10·11·12 7·2·9·2·11·2 252
⎜ ⎟ = ――――― = ―――――――――――――― = ―――――――――――― = 924 = ――― · 11
⎝ 6 ⎠ 6!·6! 1·2·3·4·5·6 1·2·3 3
Now we can derive a couple of recurrence relations that let us evaluate the sum at a given n from the sum at n - 1
sum(1) = 2
sum(n-1)
sum(n) = ―――――――― · (2·n - 1) when n is even
n/2
sum(n-1)
sum(n) = ―――――――― · (2·n - 1) · 2 when n is odd
n
Note that the divisions (which are always exact, but I won't demonstrate that) are performed before the multiplications, avoiding unnecessary overflows.
Those formulas produce the following sequence
1 2
2 6
3 20
4 70
5 252
6 924
7 3432
8 12870
9 48620
10 184756
11 705432
12 2704156
13 10400600
14 40116600
15 155117520
16 601080390
17 2333606220
18 9075135300
19 35345263800
20 137846528820
21 538257874440
22 2104098963720
23 8233430727600
24 32247603683100
25 126410606437752
26 495918532948104
27 1946939425648112
28 7648690600760440
29 30067266499541040
30 118264581564861424
31 465428353255261088
32 1832624140942590534
33 7219428434016265740
The next value, 34, can't be calculated this way (using a 64-bit type).
28! = 304888344611713860501504000000 which is larger than maximum unsigned long long 18446744073709551615. It wraps over (modulo ULLONG_MAX)and the result is smaller than k. The division will be 0
You use the wrong printf format.
unsigned long long factorial(unsigned long long n)
{
if (n == 0) return 1;
return n * factorial(n - 1);
}
unsigned long sum_squared(const int line)
{
unsigned long long n = 2*line;
unsigned long long x1 = factorial(line);
unsigned long long k = x1*x1;
unsigned long long x = factorial(n)/(k);
printf("%llu %llu %llu %llu %llu\n", n, x1, k, x , factorial(n));
return x;
}
int main(void)
{
printf("%llu\n", sum_squared(14));
}
output:
28 87178291200 18442642257371725824 0 12478583540742619136
18417982275456073728
Related
#include <stdio.h>
int F(int L[], int p, int q) {
if (p < q) {
int r, f1, f2;
r = (p + q) / 2;
f1 = 2 * F(L, p, r);
f2 = 2 * F(L, r + 1, q);
return f1 + f2;
} else if (p == q) {
return L[p] * L[p];
}else{
return 0;
}
}
int main(void) {
int arr[8] = {1,2,3,4,5,6,7};
printf("%d", F(arr, 0, 7));
}
Someone said the time complexity of this code is O(n).
I don't understand it at all...
Isn't it O(logN) ???
Answer: The Big-O complexity is O(N)
Explanation:
The program takes a range of some size (i.e. q - p + 1) and cut that range into 2 half. Then it calls the function recursively on these two half ranges.
That process continues until the range has size 1 (i.e. p == q). Then there is no more recursion.
Example: Consider a start range with size 8 (e.g. p=0, q=7) then you will get
1 call with range size 8
2 calls with range size 4
4 calls with range size 2
8 calls with range size 1
So 7 calls (i.e. 1+2+4) with range size greater than 1 and 8 calls with range size equal to 1. A total of 15 calls which is nearly 2 times the starting range size.
So for a range size being a power of 2, you can generalize to be
Number of calls with range size greater than 1:
1+2+4+8+16+...+ rangesize/2 = rangesize - 1
Number of calls with range size equal to 1:
rangesize
So there will be exactly 2 * rangesize - 1 function calls when range size is a power of 2.
That is Big-O complexity O(N).
Want to try it out?
#include <stdio.h>
unsigned total_calls = 0;
unsigned calls_with_range_size_greater_than_one = 0;
unsigned calls_with_range_size_equal_one = 0;
int F(int L[], int p, int q) {
++total_calls;
if (p < q) {
++calls_with_range_size_greater_than_one;
int r, f1, f2;
r = (p + q) / 2;
f1 = 2 * F(L, p, r);
f2 = 2 * F(L, r + 1, q);
return f1 + f2;
} else if (p == q) {
++calls_with_range_size_equal_one;
return L[p] * L[p];
}else{
return 0;
}
}
int arr[200] = {1,2,3,4,5,6,7};
int main(void) {
for (int i=3; i < 128; i = i + i + 1)
{
total_calls=0;
calls_with_range_size_greater_than_one=0;
calls_with_range_size_equal_one=0;
F(arr, 0, i);
printf("Start range size: %3d -> total_calls: %3u calls_with_range_size_greater_than_one: %3u calls_with_range_size_equal_one: %3u\n", i+1, total_calls, calls_with_range_size_greater_than_one, calls_with_range_size_equal_one);
}
return 0;
}
Output:
Start range size: 4 -> total_calls: 7 calls_with_range_size_greater_than_one: 3 calls_with_range_size_equal_one: 4
Start range size: 8 -> total_calls: 15 calls_with_range_size_greater_than_one: 7 calls_with_range_size_equal_one: 8
Start range size: 16 -> total_calls: 31 calls_with_range_size_greater_than_one: 15 calls_with_range_size_equal_one: 16
Start range size: 32 -> total_calls: 63 calls_with_range_size_greater_than_one: 31 calls_with_range_size_equal_one: 32
Start range size: 64 -> total_calls: 127 calls_with_range_size_greater_than_one: 63 calls_with_range_size_equal_one: 64
Start range size: 128 -> total_calls: 255 calls_with_range_size_greater_than_one: 127 calls_with_range_size_equal_one: 128
I've already written a program, but it's a bit incorrect.
I will be very grateful if you show me how to fix it.
So, here is the trouble:
You have to convert the number from hexadecimal to decimal form.
The main problem is that program must CALCULATE MANUALLY the number , instead of using a format specification ( as i did )
I apologize for possible inaccuracies and mistakes in English, I am just starting to familiarize myself with programming))
There is my variant:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define SIZE 20
int main(void) {
system("chcp 1251");
char str[SIZE][SIZE], (*pstr)[SIZE];
pstr = str;
char* pcode;
int kst;
printf("Specify the number of lines you want to enter: ");
scanf_s("%d", &kst);
getchar();
while (kst > SIZE)
{
printf("You have exceeded the allowed value (the number of lines must be less than 20): ");
scanf_s("%d", &kst);
getchar();
}
while (kst < 1)
{
printf("You entered a number that is too small, try entering a number between 1 and 20:");
scanf_s("%d", &kst);
getchar();
}
int isXDigit;
printf("\nEnter the lines:\n\n");
while (pstr < str + kst)
{
isXDigit = 1;
gets_s(*pstr);
for (pcode = *pstr; *pcode != '\0'; pcode++){
if (isxdigit(*pcode) == 0){
**pstr = 0;
break;
}
}
pstr++;
}
printf("\nThe result\n");
unsigned long long sixteen;
for (pstr = str; pstr < str + kst; pstr++)
{
if (**pstr == 0)
printf("16: The error!\n");
else {
sixteen = strtoull (*pstr, NULL, 16);
printf("16: %#020llx | 10: %llu\n", sixteen, sixteen);
}
}
return 0;
}
unsigned long long hexToNum(const char *hexSTR)
{
const char *digits = "0123456789ABCDEF";
const char *found = NULL;
unsigned long long result = 0;
while(*hexSTR)
{
result *= 0x10;
if(found = strchr(digits, toupper((unsigned char)*hexSTR)))
result += found - digits;
else { result = 0; break;}
hexSTR++;
}
return result;
}
Textual representation of a number
“Hexadecimal” and “decimal” (and “octal” and “binary” et cetera) are all textual representations of a number.
That is, we write numbers with a radix, but a number exists independently of any particular representation.
That is why 0xA equals 10 equals 012 equals 0b1010 (hexadecimal, decimal, octal, and binary representations).
Remember in grade school when you were taught digit places? That is because a number is a polynomial representation of a value.
→ 123 equals 100 + 20 + 3
Or, written as a polynomial:
→ 1×102 + 2×101 + 3×100
That 10 is the radix. If we change the radix, the number gets written differently. The following, even though it has the same digits, is a totally different number:
→ 1×162 + 2×161 + 3×160
We can see this by doing the math.
3×160 is 3
2×161 is 32
1×162 is 256
256 + 32 + 3 is 291
Dissecting a number to a polynomial representation with radix
To get the least-significant digit of a number, you simply take the remainder of dividing it by the radix:
→ 123 ÷ 10 is 12 with a remainder of 3
You can repeat this process to get every digit in the given radix:
→ 12 ÷ 10 is 1 with a remainder of 2
→ 1 ÷ 10 is 0 with a remainder of 1
So the digits, radix 10, of 123 are, least-significant to most-significant, 3, 2, and 1. We write this as 123.
Suppose we take a radix of 16?
→ 123 ÷ 16 is 7 with a remainder of 11 (which we write as B)
→ 7 ÷ 16 is 0 with a remainder of 7
So the hexadecimal (radix == 16) value of 123 is 7B.
Suppose we take a radix of 8?
→ 123 ÷ 8 is 15 with remainder 3
→ 15 ÷ 8 is 1 with remainder 7
→ 1 ÷ 8 is 0 with remainder 1
So the octal (radix == 8) value of 123 is 173.
In C the operators for getting the quotient and remainder are / and %:
42 / 10 is 4 (quotient)
42 % 10 is 2 (remainder)
Building a number from a polynomial representation with radix
If you are given a textual number representation and wish to build that into an actual numeric value, you only need to know the radix and have access to multiplication and addition.
For example, given 2 7 B:
0 * 16 + 2 → 0 + 2 → 2
2 * 16 + 7 → 32 + 7 → 39
39 * 16 + 11 → 624 + 11 → 635
Indeed this is correct: The hexadecimal representation of 635 is 27B. Said another way, the decimal representation of 0x27B is 635.
Functions!
We can make ourselves functions both to build and dissect polynomial text representations.
int hex_to_int( const char * text );
void int_to_hex( int number, char result[] );
Digit symbols
One thing to be aware of is the number of digit symbols available to a given radix.
For decimal we use the digit symbols 0 through 9.
For octal we only use the digit symbols 0 through 7.
For binary we only need 0 and 1.
But we don’t have enough Arabic digit symbols for hexadecimal, which needs 16 digit symbols. So we just start using the alphabet:
→ 0 1 2 3 4 5 6 7 8 9 A B C D E F
Converting to hex is easy. Just use an array:
char digits[] = "0123456789ABCDEF";
To output the digit symbol for digit 13, just use the array:
printf( "%c", digits[13] ); // prints "D"
Going the other way is a little trickier. I recommend you make yourself a little function:
int hex_digit_to_value( int digit )
{
if ((digit >= '0') and (digit <= '9')) return (digit - '0');
if ((digit >= 'A') and (digit <= 'F')) return (digit - 'A') + 10;
if ((digit >= 'a') and (digit <= 'f')) return (digit - 'a') + 10;
return 0; // can't happen? maybe return -1?
}
I was practicing programming in C, and when I ran this code, it came to a point where the outputting numbers just gave up lol, it was around the 30th number of the sequence.
What is the limit to output numbers in C?
(I was trying the Fibonacci sequence)
int main() {
int fibo, i, n, a, aux;
printf("Enter a number: ");
scanf("%d", &fibo);
n = 1; a = 1;
printf("1 1 ");
for(i = 3; i <= fibo; i++){
/* aux = n;
n = n + a;
a = aux;*/
n += a;
a = n - a;
printf("%d ", n);
}
}
What is the limit to output numbers in C?
There is no such limit. You can create a library to do arithmetic operations on arbitrary large numbers - and output them.
The question should probably be "what ranges can the fundamental types in C represent?" - and there are different limits for the different fundamental types.
Here's an incomplete list of some types taken from limits.h:
INT_MIN - minimum value of int
INT_MAX - maximum value of int
LLONG_MIN - minimum value of long long int
LLONG_MAX - maximum value of long long int
And from float.h:
DBL_MIN - minimum, normalized, positive value of double (typically 0.)
-DBL_MAX - lowest finite value representable by double
DBL_MAX - maximum finite value of duuble
Note that
an int is required to be at least 16 bit wide, but is often 32.
a long int is required to be at least 32 bit wide and often is.
a long long int is required to be at least 64 bites wide.
Depending on the type's bit width and how the implementation make use of these bits (two's complement, ones' complement, sign–magnitude and for floating points, if they use IEEE 754 or something else) affects the ranges they can represent.
Fibonacci numbers get very large very quickly, and will exceed the range of native integer types for relatively small n. On my system, the largest Fibonacci number I can compute with the following code using a regular signed int is F(44):
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
int main( int argc, char **argv )
{
if ( argc < 2 )
{
fprintf( stderr, "USAGE: %s n\n", argv[0] );
exit( 0 );
}
int n = strtol( argv[1], NULL, 10 );
int f[3] = { 0, 1, 0 };
printf( "INT_MAX = %d\n", INT_MAX );
for ( int i = 1; i <= n && INT_MAX - f[2] > f[1] + f[0]; i++ )
{
f[2] = f[1] + f[0];
f[0] = f[1];
f[1] = f[2];
printf( "fib %3d = %10d\n", i, f[2] );
}
return 0;
}
Output:
$ ./fib 50
INT_MAX = 2147483647
fib 1 = 1
fib 2 = 2
fib 3 = 3
fib 4 = 5
fib 5 = 8
fib 6 = 13
fib 7 = 21
fib 8 = 34
fib 9 = 55
fib 10 = 89
fib 11 = 144
fib 12 = 233
fib 13 = 377
fib 14 = 610
fib 15 = 987
fib 16 = 1597
fib 17 = 2584
fib 18 = 4181
fib 19 = 6765
fib 20 = 10946
fib 21 = 17711
fib 22 = 28657
fib 23 = 46368
fib 24 = 75025
fib 25 = 121393
fib 26 = 196418
fib 27 = 317811
fib 28 = 514229
fib 29 = 832040
fib 30 = 1346269
fib 31 = 2178309
fib 32 = 3524578
fib 33 = 5702887
fib 34 = 9227465
fib 35 = 14930352
fib 36 = 24157817
fib 37 = 39088169
fib 38 = 63245986
fib 39 = 102334155
fib 40 = 165580141
fib 41 = 267914296
fib 42 = 433494437
fib 43 = 701408733
fib 44 = 1134903170
If I switch to unsigned int, I can compute up to F(45). If I use long, I can get up to F(90). But even if I use unsigned long long, I'll still exceed its range with relatively small n.
To compute Fibonacci sequences for arbitrarily large n, you'll need a third-party bignum library like GMP:
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <gmp.h>
int main( int argc, char **argv )
{
if ( argc < 2 )
{
fprintf( stderr, "USAGE: %s n\n", argv[0] );
exit( 0 );
}
int n = strtol( argv[1], NULL, 10 );
mpz_t f[3];
mpz_init_set_str( f[0], "1", 10 );
mpz_init_set_str( f[1], "1", 10 );
for ( int i = 1; i <= n; i++ )
{
mpz_add( f[2], f[1], f[0] );
mpz_set( f[0], f[1] );
mpz_set( f[1], f[2] );
gmp_printf( "fib %d = %Zd\n", i, f[2] );
}
return 0;
}
For n == 1000, I get
fib 1000 = 113796925398360272257523782552224175572745930353730513145086634176691092536145985470146129334641866902783673042322088625863396052888690096969577173696370562180400527049497109023054114771394568040040412172632376
Edit
Gah, the sequence starts off wrong - it should be 1, 1, 2, .... But my main point remains.
There is a problem which i am working on it right now and it's as the following :
there are two numbers x1 and x2 and x2 > x1.
for example x1 = 5; and x2 = 10;
and I must find the sum of ones between x1 and x2 in binary representations.
5 = 101 => 2 ones
6 = 110 => 2 ones
7 = 111 => 3 ones
8 = 1000 => 1 one
9 = 1001 => 2 ones
10= 1010 => 2 ones
so the sum will be
sum = 2 + 2 + 3 + 1 + 2 + 2 = 12 ones;
so I have managed to make a code without even transfer the numbers to binary and wasting execution time.
I noticed that the numbers of ones in every 2^n with n >= 1 is 1
Ex : 2^1 => num of ones is 1
2^2 => 1 2^15 => 1
you can test it here if you want: https://www.rapidtables.com/convert/number/decimal-to-binary.html?x=191
and between each 2^n and 2^(n+1) there are Consecutive numbers as you will see in this example :
num number of ones
2^4 = 16 1
17 2
18 2
19 3
20 2
21 3
22 3
23 4
24 2
25 3
26 3
27 4
28 3
29 4
30 4
31 5
2^5 = 32 1
so I write a code that can find how many ones between 2^n and 2^(n+1)
int t; ////turns
int bin = 1; //// numbers of ones in the binary format ,,, and 1 for 2^5
int n1 = 32; //// 2^5 this is just for clarification
int n2 = 64; //// 2^6
int *keep = malloc(sizeof(int) * (n2 - n1); ///this is to keep numbers because
/// i'll need it later in my consecutive numbers
int i = 0;
int a = 0;
n1 = 33 //// I'll start from 33 cause "bin" of 32 is "1";
while (n1 < n2) /// try to understand it now by yourself
{
t = 0;
while (t <= 3)
{
if (t == 0 || t == 2)
bin = bin + 1;
else if (t == 1)
bin = bin;
else if (t == 3)
{
bin = keep[i];
i++;
}
keep[a] = bin;
a++;
t++;
}
n1++;
}
anyway as you see I am close to solve the problem but they give me huge numbers and I must find the ones between them, unfortunately I have tried a lot of methods to calculate the "sum" using this above code and I ended up with time execution problem.
Ex: 1, 1000000000 the numbers of ones is >>> 14846928141
so can you give me a little hint what to do next, thanks in advance.
I'm doing this for CodeWar challenge: https://www.codewars.com/kata/596d34df24a04ee1e3000a25/train/c
You can solve this problem by computing the number of bits in the range 1 to n and use a simple subtraction for any subrange:
#include <stdio.h>
#include <stdlib.h>
/* compute the number of bits set in all numbers between 0 and n excluded */
unsigned long long bitpop(unsigned long long n) {
unsigned long long count = 0, p = 1;
while (p < n) {
p += p;
/* half the numbers in complete slices of p values have the n-th bit set */
count += n / p * p / 2;
if (n % p >= p / 2) {
/* all the numbers above p / 2 in the last partial slice have it */
count += n % p - p / 2;
}
}
return count;
}
int main(int argc, char *argv[]) {
unsigned long long from = 1000, to = 2000;
if (argc > 1) {
to = from = strtoull(argv[1], NULL, 0);
if (argc > 2) {
to = strtoull(argv[1], NULL, 0);
}
}
printf("bitpop from %llu to %llu: %llu\n", from, to, bitpop(to + 1) - bitpop(from));
return 0;
}
Here is a proposal for a speedup:
Find smallest y1 such that y1 >= x1 and that y1 is a power of 2
Find largest y2 such that y2 <= x2 and that y2 is a power of 2
Find p1 and p2 such that 2^p1=y1 and 2^p2=y2
Calculate the amount of 1:s between y1 and y2
Deal with x1 to y1 and y2 to x2 separately
Sum the results from 4 and 5
Let's focus on step 4. Let f(n) be the sum of ones up to (2^n)-1. We can quickly realize that f(n) = 2*f(n-1) + 2^(n-1) and that f(1)=1. This can be even further refined so that you don't have to deal with recursive calls, but I highly doubt it will be of any importance. Anyway, f(n) = n*2^(n-1)
To get the result between y1 and y2, just use f(p2)-f(p1)
For step 5, you can likely use a modified version of step 4.
EDIT:
Maybe I was to quick to say "quickly realize". Here is a way to understand it. The amounts of ones up to 2¹-1 is easy to see. The only two binary numbers below 2¹ are 0 and 1. To get the number of ones up to 2² we take the numbers below 2¹ and make a column:
0
1
Clone it:
0
1
0
1
And put 0:s before the first half and 1:s before the second half:
00
01
10
11
To get 2³ we do the same. Clone it:
00
01
10
11
00
01
10
11
And add 0 and 1:
000
001
010
011
100
101
110
111
Now it should be easy to see why f(n) = 2*f(n-1) + 2^(n-1). The cloning gives 2f(n-1) and adding the 0:s and 1:s gives 2^(n-1). If 2^(n-1) is hard to understand, remember that 2^(n-1)=(2^n)/2. In each step we have 2^n rows and half of them get an extra 1.
EDIT2:
When I looked at these columns, I got an idea for how to do step 5. Let's say that you want to find the amounts of 1:s from 10 to 15. Binary table for this would be:
10: 1010
11: 1011
12: 1100
13: 1101
14: 1110
15: 1111
Look at the interval 12-15. The last two digits in binary is a copy of the corresponding table for 0-3. That could be utilized, but I leave that to you.
EDIT 3:
This was a fun problem. I wrote some python code that does this. I get some problems with too many recursive calls, but that could be solved pretty easily, and it should not be too complicated to convert this to C:
def f(n):
return n*2**(n-1)
def numberOfOnes(x):
if(x==0):
return 0
p = floor(log(x,2))
a = f(p)
b = numberOfOnes(x-2**p)
c = x - 2**p +1
return a+b+c
I made an image so that you easier can understand what a, b and c does in the function numberOfOnes if we call it with numberOfOnes(12):
I have finally converted it to C. Of course I have used some code I found here on Stack overflow. I borrowed code for integer versions of log2 and pow, and made some small modifications.
This code is probably possible to optimize further, but it is not necessary. It is lighting fast, and I was not able to measure it's performance.
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <stdint.h>
#include <inttypes.h>
typedef uint64_t T;
// https://stackoverflow.com/a/11398748/6699433
const int tab64[64] = {
63, 0, 58, 1, 59, 47, 53, 2,
60, 39, 48, 27, 54, 33, 42, 3,
61, 51, 37, 40, 49, 18, 28, 20,
55, 30, 34, 11, 43, 14, 22, 4,
62, 57, 46, 52, 38, 26, 32, 41,
50, 36, 17, 19, 29, 10, 13, 21,
56, 45, 25, 31, 35, 16, 9, 12,
44, 24, 15, 8, 23, 7, 6, 5};
T log2_64 (T value) {
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value |= value >> 32;
return tab64[((T)((value - (value >> 1))*0x07EDD5E59A4E28C2)) >> 58];
}
// https://stackoverflow.com/a/101613/6699433
T ipow(T base, T exp) {
T result = 1;
for (;;) {
if (exp & 1) result *= base;
exp >>= 1;
if (!exp) break;
base *= base;
}
return result;
}
T f(T n) { return ipow(2,n-1)*n; }
T numberOfOnes(T x) {
if(x==0) return 0;
T p = floor(log2(x));
T a = f(p);
T e = ipow(2,p);
T b = numberOfOnes(x-e);
T c = x - e + 1;
return a+b+c;
}
void test(T u, T v) {
assert(numberOfOnes(u) == v);
}
int main() {
// Sanity checks
test(0,0);
test(1,1);
test(2,2);
test(3,4);
test(4,5);
test(5,7);
test(6,9);
// Test case provided in question
test(1000000000,14846928141);
}
int x1 = 5;
int x2 = 10;
int i=0;
int looper = 0;
unsigned long long ones_count = 0;
for(i=x1; i<=x2; i++){
looper = i;
while(looper){
if(looper & 0x01){
ones_count++;
}
looper >>= 1;
}
}
printf("ones_count is %llu\n", ones_count);
return 0;
OUTPUT: ones_count is 12
Here is a way to count every single bit for every value in between the two values. The shift/mask will be faster than your arithmetic operators most likely, but will still probably time out. You need a clever algorithm like the other answer suggests i think, but heres the stupid brute force way :)
This was my solution to the problem:
** = exponentiation
/ = whole number division
Consider the numbers from 1 to 16:
00001
00010
00011
00100
00101
00110
00111
01000
01001
01010
01011
01100
01101
01110
01111
10000
If you pay attention to each column, you'll notice a pattern. The bit at column index i (0,1,2 ...) from the right runs through a cycle of length 2**(i+1), that is every 2**(i+1) rows, the pattern in column i repeats itself. Notice also that the first cycle starts at the first occurrence of a 1 in a given column. The number of ones in a pattern is half of the patterns length.
Example:
i pattern
0 10
1 1100
2 11110000
3 1111111100000000
...
So, given the task of summing all ones up to n, we have to keep track of how many times each pattern repeats itself and also if a pattern fails to complete itself.
Solution:
Let x be the biggest exponent of a binary number n and let s be the sum of all ones up to n. Then, for i = (0, 1, 2, ... , x) add (n / 2**(i+1)*(2**i) to s. If the remainder is bigger than 2**i, add 2**i to s, else add the remainder. Then subtract 2**i from n and repeat the process.
Example:
n = 7 -> x = 2
(7 / 2**1)*(2**0) = 3
7 % 2**1 = 1 !> 2**0
s = 1 + 3 (4)
n = n - 2**0 (6)
(6 / 2**2)*(2**1) = 2
6 % 2**2 = 2 !> 2**1
s = s + 2 + 2 (8)
n = n - 2**1 (4)
(4 / 2**3)*(2**2) = 0
4 % 2**3 = 4 !> 2**2
s = s + 4 (12)
n = n - 2**2 (0)
s = 12
Maybe not the best explanation or the most beautiful solution, but it works fine.
In python:
def cnt_bin(n):
bits = n.bit_length()
s = 0
for i in range(bits):
s += (n // 2**(i+1))*2**i
if n % 2**(i+1) > 2**i:
s += 2**i
else:
s += (n % 2**(i+1))
n -= 2**i
return s
Then, for a range [a, b] you just compute cnt_bin(b) - cnt_bin(a-1)
i am not understanding this modulo in c languge.
For example:
#include <stdio.h>
#include<math.h>
int main()
{
int my_input[] = {23, 22, 21, 20, 19, 18};
int n, mod;
int nbr_items = sizeof(my_input) / sizeof(my_input[0]);
for (n = 0; n < nbr_items; n++)
{
mod = my_input[n] % 4;
printf("%d modulo %d --> %d\n", my_input[n], 4, mod);
}
}
Gives:
23 modulo 4 --> 3
22 modulo 4 --> 2
21 modulo 4 --> 1
20 modulo 4 --> 0
19 modulo 4 --> 3
18 modulo 4 --> 2
I would have expected a number that i can make sense of.
Essentially i am trying to test if a number is divisible by 4.
The modulo operator in C will give the remainder that is left over when one number is divided by another. For example, 23 % 4 will result in 3 since 23 is not evenly divisible by 4, and a remainder of 3 is left over.
If you want to output whether or not a number is divisible by 4, you need to output something other than just the mod result. Essentially, if mod = 0 than you know that one number is divisible by another.
If you want to output whether or not the number is divisible by 4, I would suggest creating a new character that is set to "y" (yes) or "n" (no) depending on the result of the mod operation. Below is one possible implementation to generate a more meaningful output:
#include <stdio.h>
#include <ctype.h>
#include <math.h>
int main()
{
int my_input[] = {23, 22, 21, 20, 19, 18};
int n, mod;
char is_divisible;
int nbr_items = sizeof(my_input) / sizeof(my_input[0]);
for (n = 0; n < nbr_items; n++)
{
mod = my_input[n] % 4;
is_divisible = (mod == 0) ? 'y' : 'n';
printf("%d modulo %d --> %c\n", my_input[n], 4, is_divisible);
}
}
This will give the following:
23 modulo 4 --> n
22 modulo 4 --> n
21 modulo 4 --> n
20 modulo 4 --> y
19 modulo 4 --> n
18 modulo 4 --> n
I'm sure we know the basic division equation from high school math
dividend = divisor*quotient + remainder
Now:
1. The "/" operator gives us the quotient.
2. The "%" operator gives us the remainder
example:
say a = 23, b = 4
a / b = 23 / 4 = 5
a % b = 23 % 4 = 3
23 = 4*5 + 3
Here 4 is the quotient and 3 is the remainder.
If a number is perfectly divisible by a divisor, then remainder is zero.
So:
20/4 = 5 (quotient)
20%4 = 0 (remainder)
To test if a no if divisible by 4, the check should be something like if (num % 4 == 0).
Hope this helps!