#include "stdio.h"
int bdiv( int dividend , int divisor )
{
int remainder = dividend ;
int quotient = 0 ;
int i ;
for( i = 0 ; i < 17 ; i++ )
{
remainder = remainder - divisor ;
if( (remainder & 0x8000) )
{
remainder = remainder + divisor ;
quotient = quotient << 1 ;
}
else
quotient = ( quotient << 1 ) | 0x1 ;
divisor = divisor >> 1 ;
}
return quotient ;
}
int main()
{
int a = 7 ;
int b = 2 ;
printf( "%d\n" , bdiv(a,b) ) ;
}
Pseudo-Code of the algorithm I tried to implement :
START
Remainder = Dividend ;
Quotient = 0 ;
1.Subtract Divisor register from remainder and place result in remainder .
2. Test Remainder
2a . If remainder >= 0 shift quotient to right setting rightmost bit to 1
2b. If remainder < 0 , restore the original value of the remainder register . Also shift the quotient register to the left setting the new least significant bit to 0 .
3. Shift the divisor right 1 bit .
4. is it the 33rd repetition ( for 32 bit division ) ? No : GOTO 1
Yes : STOP
I wrote this program for binary division in C for 16 bit division and it's not working . Can anyone suggest me what's not working ?
It is giving output as 131071 for a division of 7 by 2 .
The second shift needs to be:
quotient = (( quotient >> 1 ) | 0x1) ;
Also, why not:
if (remainder < 0 )
???
#include "stdio.h"
int bdiv( int dividend , unsigned divisor )
{
divisor<<=16;
int i = 17 ;
do {
dividend -= divisor ;
if (dividend < 0) dividend += divisor ;
else dividend++;
i--;
if (i) dividend<<=1;
// printf( "%d, %d\n" , dividend, divisor ) ;
} while (i);
return dividend ;
}
int main()
{
int a []= {631, 76, 760, 7600, 76000, 450333, 450333, 450333, 450333};
int b []= {7, 75, 750, 7500, 75000, 77, 777, 7777, 77777} ;
union doubleint {
struct {
short int quotient;
short unsigned remainder;
}part;
int value;
} c;
for (unsigned char i = 0; i < 9; i++){
c.value = bdiv(a [i],b [i]);
printf( "%d / %d = %d + %d / %d\n" , a[i], b[i], c.part.quotient, c.part.remainder, b[i] ) ;
}
/*
unsigned c = bdiv (a,b);
printf ("%d, %d\n", c&0xffff, (c>>16)&0xffff);
*/
}
/*
631 / 7 = 90 + 1 / 7 Correct
76 / 75 = 1 + 1 / 75 Correct
760 / 750 = 1 + 10 / 750 Correct
7600 / 7500 = 1 + 100 / 7500 Correct
76000 / 75000 = 8 + 288 / 75000 WRONG: 75000 doesn't fit in 2 bytes
450333 / 77 = 5848 + 37 / 77 Correct: dividend does not have to fit in 2 bytes
450333 / 777 = 579 + 450 / 777 Correct
450333 / 7777 = 57 + 7044 / 7777 Correct
450333 / 77777 = 36 + 9657 / 77777 WRONG: 77777 does not fit in 2 bytes
*/
Related
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.
So I want to start by saying that I already solved the problem, but there is something that is bugging me,
Here is the code first:
#include <stdio.h>
int flag = 1;
int controlNumber(int);
int main() {
int array[10] = { 233, 45, 777, 81, 999999, 36, 90, 88, 11, 61 };
int i;
int c;
for (i = 0; i < 10; i++) {
printf("%d >> ", array[i]);
c = controlNumber(array[i]);
if (c == 1) {
printf("all digits are equal\n");
} else {
printf("not all digits are equal\n");
}
}
return 0;
}
int controlNumber(int a) {
int q = a;
int r = a % 10;
int temp;
while (q != 0) {
temp = q % 10;
if (temp == r) {
q = q / 10;
} else {
flag = 0;
return flag;
}
}
return flag;
}
The code works only if the global variable flag is made local inside the scope of the function controlNumber with a value of 1, and I can't really figure out why that is the case since the logic should still be the same.
Also, I'm still a beginner to some extend so I apologize for any indentation errors.
For starters it is a very bad idea to define a function that depends on a global variable. In fact it is the reason of the bug of your program. You forgot to reset the global variable flag to 1 each time before calling the function.
The function can be defined the following way without any redundant global variable
int controlNumber( int n )
{
const int Base = 10;
int digit = n % Base;
while ( ( n /= Base ) && ( n % Base == digit ) );
return n == 0;
}
Here is a demonstrative program.
#include <stdio.h>
int controlNumber( int n )
{
const int Base = 10;
int digit = n % Base;
while ( ( n /= Base ) && ( n % Base == digit ) );
return n == 0;
}
int main(void)
{
int array[] = { 233, 45, 777, 81, 999999, 36, 90, 88, 11, 61 };
const size_t N = sizeof( array ) / sizeof( *array );
for ( size_t i = 0; i < N; i++ )
{
printf( "%d >> ", array[i] );
if ( controlNumber( array[i] ) )
{
printf( "all digits are equal\n");
}
else
{
printf( "not all digits are equal\n" );
}
}
return 0;
}
The program output is
233 >> not all digits are equal
45 >> not all digits are equal
777 >> all digits are equal
81 >> not all digits are equal
999999 >> all digits are equal
36 >> not all digits are equal
90 >> not all digits are equal
88 >> all digits are equal
11 >> all digits are equal
61 >> not all digits are equal
If for example you will change the constant Base in the function and make it equal to 8
int controlNumber( int n )
{
const int Base = 8; //10;
int digit = n % Base;
while ( ( n /= Base ) && ( n % Base == digit ) );
return n == 0;
}
then you will get the following result.
233 >> not all digits are equal
45 >> all digits are equal
777 >> not all digits are equal
81 >> not all digits are equal
999999 >> not all digits are equal
36 >> all digits are equal
90 >> not all digits are equal
88 >> not all digits are equal
11 >> not all digits are equal
61 >> not all digits are equal
In this case for example the number 45 has the same digits in the octal representation because in the octal representation the number is written like 055.
Global variables retain their value. In your case, if flag is global, once set to 0 (within controlNumber) it will keep that value. There is no other place in the code to make it 1 again.
Making it a local variable to the function will cause it to initialize to 1 every time the function is called.
Edit: if you want to have it as global, you could set it to 1 every time controlNumber returns 0, i.e., before or after printf("not all digits are equal\n");.
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 have written the following code to compute the greatest prime factor of a number supplied
through standard input but it is taking ages to execute.How can i reduce the execution time of the program?
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool is_prime(unsigned long long num)
{
if (num == 0 || num == 1)
return false;
if (num == 2)
return true;
for (unsigned long long j = 2; j < num; j++)
if(num%j==0)
return false;
return true;
}
int main(void)
{
unsigned long long n,i;
printf("enter the number: ");
scanf("%llu",&n);
for(i=n-1;i>1;i--)
if((is_prime(i)) && n%i==0)
break;
printf("%llu\n",i);
return 0;
}
Number in the input is 600851475143.
bool is_prime(unsigned long long num)
{
if (num < 2) return false; /* Reject border cases */
if (num == 2) return true; /* Accept the largest even prime */
if ((num & (~1)) == num) return false; /* Reject all other evens */
unsigned long long limit = sqrt(num) + 1; /* Limit the range of the search */
for (unsigned long long j = 3; j < limit; j += 2) /* Loop through odds only */
if(num % j==0)
return false; /* Reject factors */
return true; /* No factors, hence it is prime */
}
Have fun...one function for all prime factors, one for maximum prime factor:
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long u64_t;
static size_t prime_factors(u64_t value, u64_t *array)
{
size_t n_factors = 0;
u64_t n = value;
u64_t i;
while (n % 2 == 0)
{
n /= 2;
//printf("Factor: %llu (n = %llu)\n", 2ULL, n);
array[n_factors++] = 2;
}
while (n % 3 == 0)
{
n /= 3;
//printf("Factor: %llu (n = %llu)\n", 3ULL, n);
array[n_factors++] = 3;
}
for (i = 6; (i - 1) * (i - 1) <= n; i += 6)
{
while (n % (i-1) == 0)
{
n /= (i-1);
//printf("Factor: %llu (n = %llu)\n", (i-1), n);
array[n_factors++] = (i-1);
}
while (n % (i+1) == 0)
{
n /= (i+1);
//printf("Factor: %llu (n = %llu)\n", (i+1), n);
array[n_factors++] = (i+1);
}
}
if (n != 1)
array[n_factors++] = n;
return n_factors;
}
static u64_t max_prime_factor(u64_t value)
{
u64_t n = value;
u64_t i;
u64_t max = n;
while (n % 2 == 0)
{
n /= 2;
//printf("Factor: %llu (n = %llu)\n", 2ULL, n);
max = 2;
}
while (n % 3 == 0)
{
n /= 3;
//printf("Factor: %llu (n = %llu)\n", 3ULL, n);
max = 3;
}
for (i = 6; (i - 1) * (i - 1) <= n; i += 6)
{
while (n % (i-1) == 0)
{
n /= (i-1);
//printf("Factor: %llu (n = %llu)\n", (i-1), n);
max = (i-1);
}
while (n % (i+1) == 0)
{
n /= (i+1);
//printf("Factor: %llu (n = %llu)\n", (i+1), n);
max = (i+1);
}
}
//printf("Max Factor = %llu\n", (n == 1) ? max : n);
return (n == 1) ? max : n;
}
static void print_factors(u64_t value, size_t n_factors, u64_t *factors)
{
printf("%20llu:", value);
int len = 21;
for (size_t i = 0; i < n_factors; i++)
{
if (len == 0)
len = printf("%.21s", "");
len += printf(" %llu", factors[i]);
if (len >= 60)
{
putchar('\n');
len = 0;
}
}
if (len > 0)
putchar('\n');
}
void builtin_tests(void)
{
u64_t tests[] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 25, 49, 63, 69, 71, 73, 825, 829, 1000, 6857, 73112,
731122, 7311229, 73112293, 731122935, 7311229357, 73112293571,
600851475143, 731122935711, 7311229357111,
18446744073709551610ULL, 18446744073709551611ULL,
18446744073709551612ULL, 18446744073709551613ULL,
18446744073709551614ULL, 18446744073709551615ULL,
};
u64_t factors[64];
for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
{
u64_t max = max_prime_factor(tests[i]);
printf("%20llu -> Max Prime Factor = %llu\n", tests[i], max);
size_t n_factors = prime_factors(tests[i], factors);
print_factors(tests[i], n_factors, factors);
}
}
int main(int argc, char **argv)
{
if (argc == 1)
builtin_tests();
else
{
for (int i = 1; i < argc; i++)
{
u64_t factors[64];
u64_t value = strtoull(argv[i], 0, 0);
u64_t max = max_prime_factor(value);
printf("%20llu -> Max Prime Factor = %llu\n", value, max);
size_t n_factors = prime_factors(value, factors);
print_factors(value, n_factors, factors);
}
}
return 0;
}
Results
1 -> Max Prime Factor = 1
1:
2 -> Max Prime Factor = 2
2: 2
3 -> Max Prime Factor = 3
3: 3
4 -> Max Prime Factor = 2
4: 2 2
5 -> Max Prime Factor = 5
5: 5
6 -> Max Prime Factor = 3
6: 2 3
7 -> Max Prime Factor = 7
7: 7
8 -> Max Prime Factor = 2
8: 2 2 2
9 -> Max Prime Factor = 3
9: 3 3
10 -> Max Prime Factor = 5
10: 2 5
11 -> Max Prime Factor = 11
11: 11
12 -> Max Prime Factor = 3
12: 2 2 3
13 -> Max Prime Factor = 13
13: 13
14 -> Max Prime Factor = 7
14: 2 7
15 -> Max Prime Factor = 5
15: 3 5
16 -> Max Prime Factor = 2
16: 2 2 2 2
17 -> Max Prime Factor = 17
17: 17
18 -> Max Prime Factor = 3
18: 2 3 3
19 -> Max Prime Factor = 19
19: 19
20 -> Max Prime Factor = 5
20: 2 2 5
25 -> Max Prime Factor = 5
25: 5 5
49 -> Max Prime Factor = 7
49: 7 7
63 -> Max Prime Factor = 7
63: 3 3 7
69 -> Max Prime Factor = 23
69: 3 23
71 -> Max Prime Factor = 71
71: 71
73 -> Max Prime Factor = 73
73: 73
825 -> Max Prime Factor = 11
825: 3 5 5 11
829 -> Max Prime Factor = 829
829: 829
1000 -> Max Prime Factor = 5
1000: 2 2 2 5 5 5
6857 -> Max Prime Factor = 6857
6857: 6857
73112 -> Max Prime Factor = 37
73112: 2 2 2 13 19 37
731122 -> Max Prime Factor = 52223
731122: 2 7 52223
7311229 -> Max Prime Factor = 24953
7311229: 293 24953
73112293 -> Max Prime Factor = 880871
73112293: 83 880871
731122935 -> Max Prime Factor = 89107
731122935: 3 5 547 89107
7311229357 -> Max Prime Factor = 7311229357
7311229357: 7311229357
73112293571 -> Max Prime Factor = 8058227
73112293571: 43 211 8058227
600851475143 -> Max Prime Factor = 6857
600851475143: 71 839 1471 6857
731122935711 -> Max Prime Factor = 4973625413
731122935711: 3 7 7 4973625413
7311229357111 -> Max Prime Factor = 12939061
7311229357111: 547 1033 12939061
18446744073709551610 -> Max Prime Factor = 1504703107
18446744073709551610: 2 5 23 53301701 1504703107
18446744073709551611 -> Max Prime Factor = 287630261
18446744073709551611: 11 59 98818999 287630261
18446744073709551612 -> Max Prime Factor = 2147483647
18446744073709551612: 2 2 3 715827883 2147483647
18446744073709551613 -> Max Prime Factor = 364870227143809
18446744073709551613: 13 3889 364870227143809
18446744073709551614 -> Max Prime Factor = 649657
18446744073709551614: 2 7 7 73 127 337 92737 649657
18446744073709551615 -> Max Prime Factor = 6700417
18446744073709551615: 3 5 17 257 641 65537 6700417
The if statement in the loop in main() should check n%i==0 first so that non-factors are not checked for primeness. This alone makes the program over 200 times faster on all the numbers from 1 to 2000 on a simple test case I ran on a modern Intel CPU. The mod below just to main() (I broke it out into a function returning the largest prime factor) improves the speed significantly more. I also consider the number itself as a possible factor (not done in the original).
unsigned long long largest_prime_factor(unsigned long long n)
{
unsigned long long i,sqrtn,maxprime;
if (is_prime(n))
return(n);
sqrtn=(unsigned long long)sqrt((double)n);
maxprime=1;
for (i=2;i<=sqrtn;i++)
{
if (n%i==0)
{
unsigned long long f;
f=n/i;
if (is_prime(f))
return(f);
if (is_prime(i))
maxprime=i;
}
}
return(maxprime);
}
keeping the same logic you can reduce time by executing loop till sqrt(num) only.
because if it is not prime, there would be at least one divisor which is less then sqrt(num).
Let's take num is not prime. so for some 1< a < num, a*b = num.
so either a or b should be less than sqrt(num).
Hence your code be for is_prime should be changed to the one as follows
bool is_prime(unsigned long long num)
{
if (num == 0 || num == 1)
return false;
if (num == 2)
return true;
long long root_num = sqrt(num);
for (unsigned long long j = 2; j < root_num; j++)
if(num%j==0)
return false;
return true;
}
Now if you want to change your logic, then there is an algorithm called sieve method which finds all prime numbers which are less than given number. check this out Sieve Algorithm
Its better to start for loop from square root of number to 3,
again you can skip even numbers.
so that you can get answer within small time..
I want to list combinations of o & 1 recursively using c depending on variables number (number)
the output I want is
000
001
010
011
100
101
110
111
I've tried many algorithms the last one is :
void permute(unsigned number) {
if(number == 0) {
printf("\n");
return;
}
permute(number - 1);
printf("0");
permute(number - 1);
printf("1");
} //permute ends here
void permuteN(unsigned number) {
unsigned i;
for(i = 0; i < number + 1; i++){
permute(i);
}
} //permuteN ends here
I think it gives me the answer but not ordered because I don't know where to put \n;
need your help!
If you are indeed just looking for combinations of 1's and 0's I'd suggest you just count up the numbers and list them in binary.
Take the numerals 0...7 in binary and taking only the last 3 bits (apply mask maybe), and you end up with the same set you specified:
000
001
...
...
111
For n-digit combinations, you need to do 0..2^n - 1
Based off this answer, for one specific case of 3-bits
(Credit to #ChrisLutz and #dirkgently)
#include <stdio.h>
int main(){
int numdigits = 3, j;
for(j=1; j<8; j++)
printbits(j);
}
void printbits(unsigned char v) {
int i;
for(i = 2; i >= 0; i--) putchar('0' + ((v >> i) & 1));
printf("\n");
}
Output:
000
001
010
011
100
101
110
111
All you are actually doing is converting a number to binary.... A simple loop does this without any library calls (aside from printf)...
const unsigned int numbits = 3;
unsigned int bit;
for( bit = 1U << (numbits-1); bit != 0; bit >>= 1 ) {
printf( number&bit ? "1" : "0" );
}
printf( "\n" );
Edited, since you seem to want recursion. You need to have some way to specify how many bits you require. You need to pass this into your recursive routine:
#include <stdio.h>
void permute(unsigned number, unsigned bits)
{
if( bits == 0 ) return;
permute(number / 2, bits-1);
printf( "%d", number % 2 );
} //permute ends here
void permuteN(unsigned number, unsigned bits ) {
unsigned i;
for(i = 0; i < number + 1; i++){
permute(i, bits);
printf("\n");
}
} //permuteN ends here
int main(void)
{
permuteN(7, 3);
return 0;
}
To get the output in the order you require, you can't know when to write the newline. So in this case, you write it afterwards.
#paddy has a nice answer; only adding a bit (as of my toughs by your reply on my comment - was a bit late to the game). This rely on pow() , (and log10 for some nicety in print), tho so; if using gcc compile with -lm:
basemight be a bit confusing here - but guess you get the meaning.
gcc -Wall -Wextra -pedantic -o combo combo.c -lm
/* gcc - Wall -Wextra -pedantic -o combo combo.c -lm */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static void prnt_combo(unsigned number, unsigned bits, int base)
{
if (!bits)
return;
prnt_combo(number / base, --bits, base);
printf("%d", number % base);
}
void prnt_combos(int bits, int base)
{
int i;
int n = pow(base, bits);
int wp = log10(n) + 1;
fprintf(stderr,
"Printing all combinations of 0 to %d by width of %d numbers. "
"Total %d.\n",
base - 1, bits, n
);
for (i = 0; i < n; i++) {
fprintf(stderr, "%*d : ", wp, i);
prnt_combo(i, bits, base);
printf("\n");
}
}
/* Usage: ./combo [<bits> [<base>]]
* Defaults to ./combo 3 2
* */
int main(int argc, char *argv[])
{
int bits = argc > 1 ? strtol(argv[1], NULL, 10) : 3;
int base = argc > 2 ? strtol(argv[2], NULL, 10) : 2;
prnt_combos(bits, base);
return 0;
}
Sample:
$ ./combo 4 2
Printing all combinations of 0 to 1 by width of 4 numbers. Total 16.
0 : 0000
1 : 0001
2 : 0010
3 : 0011
4 : 0100
5 : 0101
6 : 0110
7 : 0111
8 : 1000
9 : 1001
10 : 1010
11 : 1011
12 : 1100
13 : 1101
14 : 1110
15 : 1111
Or clean output:
$ ./combo 3 2 >&2-
000
001
010
011
100
101
110
111
You might like to add something like:
if (base > 10)
printf("%x", number % base);
else
printf("%d", number % base);
in prnt_combo(). This way you get i.e. by 2 16:
0 : 00
1 : 01
2 : 02
3 : 03
4 : 04
...
250 : fa
251 : fb
252 : fc
253 : fd
254 : fe
255 : ff