This factorial function starts giving wrong results with 13 and above. I have no idea why.
#include <stdio.h>
int fatorial (int p);
int main() {
int x = 13;
int test = fatorial(x);
printf("%d", test);
}
int fatorial (int p) {
if (p <= 0)
return 1;
else
return p*fatorial(p-1);
}
for x = 0, 1, 2 ...12 it prints the right result, but for 13! it prints 1932053504 which is not correct.
For x=20 it prints -210213273 for example.
I know that this is not the best way to do a factorial. Its my homework tho, it HAS to be this way.
If you try this you will get the maximum value that int can hold:
#include <stdio.h>
#include <limits.h>
int main(void)
{
printf("%d\n", INT_MAX);
}
Your code causes overflow.
You could get a few more numbers if you use a bigger type, but not by very much. You could use this:
unsigned long long fatorial (unsigned long long p) {
if (p <= 0)
return 1;
else
return p*fatorial(p-1);
}
It won't get you far though. If you want bigger than that you need to find a library for bigger integers or create some custom solution. One such library is https://gmplib.org/ but that is likely out of scope for your homework.
And btw, a condition like p <= 0 is not good. It indicates that the factorial of a negative number is always one, which is false.
It is because after 12, the result of factorial of any number exceeds the size of int.
you can try the following code:
#include<stdio.h>
int main()
{
int a[100],n,counter,temp,i;
a[0]=1;
counter=0;
printf("Enter the number: ");
scanf("%d",&n);
for(; n>=2; n--)
{
temp=0;
for(i=0; i<=counter; i++)
{
temp=(a[i]*n)+temp;
a[i]=temp%10;
temp=temp/10;
}
while(temp>0)
{
a[++counter]=temp%10;
temp=temp/10;
}
}
for(i=counter; i>=0; i--)
printf("%d",a[i]);
return 0;
}
The result of the function is too big. I think big int would work better for your purposes. Big int allows you to have bigger numbers. Also, this is what I would do.
int x = the number you want to factorialize
int ans = 1;
(Then instead of all of those functions)
for(var i = x; i > 0; i--) {
ans = ans*i;
}
System.out.println(ans);
Javascript link: https://jsfiddle.net/8gxyj913/
I need to get to 100!
100! is about 9.332622e+157. Simply using standard integer types is insufficient. 32-bit int is good to 12!. With 64-bit integer math, code could get to about 21!
Could use floating point math and give up precision.
Instead consider a string approach.
Related
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
int rev (int N);
int rev(int N){
return ((N <= 9)) ? N : rev(N / 10) + ((N % 10) * (pow(10, (floor(log10(abs(N))))))) ;
}
int main(void){
int r, n;
scanf("%d", &n);
r = rev(n);
printf("%d %d", r, n);
return EXIT_SUCCESS;
}
A simple code just to find out the reverse of a number. Everything is fine. Until I put a number with more than 2 digits. Things behave weirdly, somehow the last digit is always 0 of the reversed number. I have checked out in online compilers where things behave just fine. However the problem arises when I run the code on my own machine. I am on Windows 10 with MINGw. Could you guys suggest me a solution. I previously had problems where the value stored in an int matrix changes to huge values which is practically impossible to store in int due to it's size.
Using the pow and floor function, working with floats will not always round the way you'd expect.
As already commented, work with integers.
Propose doing this digit-by-digit, and sticking with integers. A proposal for your rev() function:
int rev(unsigned int N)
{
unsigned int res = 0;
while(N>0)
{
// pick off lowest digit
unsigned int digit = N%10;
// put into result, moving up all previous digits by doing *10
res = 10*res+digit;
// remove this digit from input value
N/=10;
}
return res;
}
I am a beginner starting in C and am doing some exercises on codewars. The exercise requires me to take a decimal int, convert it into binary and output the number of 1s in the binary number. Below my incomplete code. I store the binary in int b and I want to output it into an array so that I can run a loop to search for the 1s and output the sum.
Thanks in advance!
#include <stddef.h>
#include <stdio.h>
//size_t countBits(unsigned value);
int countBits(int d);
int main() {
int numD = 1234;
int numB = countBits(numD);
printf("The number %d converted to binary is %d \n", numD, numB);
}
int countBits(int d) {
if (d < 2) {
return d;
} else {
int b = countBits(d / 2) * 10 + d % 2; //convert decimal into binary
int c;
int bArray[c];
}
Your function is almost correct:
you should define the argument type as unsigned to avoid problems with negative numbers
you should just return b in the else branch. Trying to use base 10 as an intermediary representation is useless and would fail for numbers larger than 1023.
Here is a corrected version:
int countBits(unsigned d) {
if (d < 2) {
return d;
} else {
return countBits(d / 2) + d % 2;
}
}
There are many more efficient ways to compute the number of bits in a word.
Check Sean Eron Anderson's Bit Twiddling Hacks for classic and advanced solutions.
You can make an array char as one of the replies said, for example:
#include <stdio.h>
#include <string.h>
int main(){
int count=0;
int n,bit;
char binary[50];
printf("Enter a binary: \n");
scanf("%s",binary);
n=strlen(binary);
for(int i=0;i<n;i++){
bit=binary[i]-'0';
if (bit==1){
count=count+1;
}
}
printf("Number of 1's: %d\n",count);
return 0;
}
This should count the number of 1's of a given binary.
Try something like this!
edit: I know that binary[i]-'0' might be confusing, if you don't understand that..take a look at this:
There are definitely 'smarter'/more compact ways to do this, but here is one way that will allow you to count bits of a bit larger numbers
#include <stdio.h>
int count_bits(int x)
{
char c_bin[33];
int count=0;
int mask=1;
for( int i =0; i < 32; i++){
if (x & mask ){
count=i+1;
c_bin[31-i]='1';
}
else{
c_bin[31-i]='0';
}
mask=mask*2;
}
c_bin[32]='\0';
printf("%d has %d bits\n",x,count);
printf("Binary x:%s\n",c_bin);
return count;
}
int main()
{
int c=count_bits(4);
return 0;
}
I've been trying to print out the Binary representation of a long long integer using C Programming
My code is
#include<stdio.h>
#include <stdlib.h>
#include<limits.h>
int main()
{
long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
scanf("%lld", &number);
while(number > 0) {
remainder = number % 2;
binaryRepresentation = binaryRepresentation + remainder * baseOfOne;
baseOfOne *= 10;
number = number / 2;
}
printf("%lld\n", binaryRepresentation);
}
The above code works fine when I provide an input of 5 and fails when the number is 9223372036854775807 (0x7FFFFFFFFFFFFFFF).
1.Test Case
5
101
2.Test Case
9223372036854775807
-1024819115206086201
Using a denary number to represent binary digits never ends particularly well: you'll be vulnerable to overflow for a surprisingly small input, and all subsequent arithmetic operations will be meaningless.
Another approach is to print the numbers out as you go, but using a recursive technique so you print the numbers in the reverse order to which they are processed:
#include <stdio.h>
unsigned long long output(unsigned long long n)
{
unsigned long long m = n ? output(n / 2) : 0;
printf("%d", (int)(n % 2));
return m;
}
int main()
{
unsigned long long number = 9223372036854775807;
output(number);
printf("\n");
}
Output:
0111111111111111111111111111111111111111111111111111111111111111
I've also changed the type to unsigned long long which has a better defined bit pattern, and % does strange things for negative numbers anyway.
Really though, all I'm doing here is abusing the stack as a way of storing what is really an array of zeros and ones.
As Bathsheba's answer states, you need more space than is
available if you use a decimal number to represent a bit sequence like that.
Since you intend to print the result, it's best to do that one bit at a time. We can do this by creating a mask with only the highest bit set. The magic to create this for any type is to complement a zero of that type to get an "all ones" number; we then subtract half of that (i.e. 1111.... - 0111....) to get only a single bit. We can then shift it rightwards along the number to determine the state of each bit in turn.
Here's a re-worked version using that logic, with the following other changes:
I use a separate function, returning (like printf) the number of characters printed.
I accept an unsigned value, as we were ignoring negative values anyway.
I process arguments from the command line - I tend to find that more convenient that having to type stuff on stdin.
#include <stdio.h>
#include <stdlib.h>
int print_binary(unsigned long long n)
{
int printed = 0;
/* ~ZERO - ~ZERO/2 is the value 1000... of ZERO's type */
for (unsigned long long mask = ~0ull - ~0ull/2; mask; mask /= 2) {
if (putc(n & mask ? '1' : '0', stdout) < 0)
return EOF;
else
++printed;
}
return printed;
}
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
print_binary(strtoull(argv[i], 0, 10));
puts("");
}
}
Exercises for the reader:
Avoid printing leading zeros (hint: either keep a boolean flag that indicates you've seen the first 1, or have a separate loop to shift the mask before printing). Don't forget to check that print_binary(0) still produces output!
Check for errors when using strtoull to convert the input values from decimal strings.
Adapt the function to write to a character array instead of stdout.
Just to spell out some of the comments, the simplest thing to do is use a char array to hold the binary digits. Also, when dealing with bits, the bit-wise operators are a little more clear. Otherwise, I've kept your basic code structure.
int main()
{
char bits[64];
int i = 0;
unsigned long long number; // note the "unsigned" type here which makes more sense
scanf("%lld", &number);
while (number > 0) {
bits[i++] = number & 1; // get the current bit
number >>= 1; // shift number right by 1 bit (divide by 2)
}
if ( i == 0 ) // The original number was 0!
printf("0");
for ( ; i > 0; i-- )
printf("%d", bits[i]); // or... putchar('0' + bits[i])
printf("\n");
}
I am not sure what you really want to achieve, but here is some code that prints the binary representation of a number (change the typedef to the integral type you want):
typedef int shift_t;
#define NBITS (sizeof(shift_t)*8)
void printnum(shift_t num, int nbits)
{
int k= (num&(1LL<<nbits))?1:0;
printf("%d",k);
if (nbits) printnum(num,nbits-1);
}
void test(void)
{
shift_t l;
l= -1;
printnum(l,NBITS-1);
printf("\n");
l= (1<<(NBITS-2));
printnum(l,NBITS-1);
printf("\n");
l= 5;
printnum(l,NBITS-1);
printf("\n");
}
If you don't mind to print the digits separately, you could use the following approach:
#include<stdio.h>
#include <stdlib.h>
#include<limits.h>
void bindigit(long long num);
int main()
{
long long number, binaryRepresentation = 0, baseOfOne = 1, remainder;
scanf("%lld", &number);
bindigit(number);
printf("\n");
}
void bindigit(long long num) {
int remainder;
if (num < 2LL) {
printf("%d",(int)num);
} else {
remainder = num % 2;
bindigit(num/2);
printf("%d",remainder);
}
}
Finally I tried a code myself with idea from your codes which worked,
#include<stdio.h>
#include<stdlib.h>
int main() {
unsigned long long number;
int binaryRepresentation[70], remainder, counter, count = 0;
scanf("%llu", &number);
while(number > 0) {
remainder = number % 2;
binaryRepresentation[count++] = remainder;
number = number / 2;
}
for(counter = count-1; counter >= 0; counter--) {
printf("%d", binaryRepresentation[counter]);
}
}
I wrote the following code to print armstrong numbers between two integers. But I am not able to find the mistake as the code looks fine to me. Please help.
void main()
{
int a,b;
printf("Enter the starting limit");
scanf("%d",&a);
printf("Enter the ending limit");
scanf("%d",&b);
int i;
int sum=0;
for(i=a+1;i<b;i++)
{
char word[50];
sprintf(word,"%d",i);
int temp=strlen(word);
int j;
for(j=0;j<temp;j++)
{
int c=i%10;
sum+=pow(c,temp);
i=i/10;
}
if (sum==i)
{
printf("%d",i);
}
}
}
As someone has answered - I will answer as well. Use only the integer arithmetic. No strings or doubles needed
#include <stdio.h>
typedef unsigned long long ull; // for convenience only
ull sum_cubes(ull num)
{
ull result = 0;
while(num)
{
unsigned digit = num % 10;
result += (ull)digit * digit * digit;
num /= 10;
}
return result;
}
#define MIN 0 //or 100 depending if 001 is the 3 digints number or not.
#define MAX 1000
int main(void)
{
for(ull num = MIN; num < MAX; num++)
{
if(num == sum_cubes(num))
{
printf("Hurray!! Found - %llu\n", num);
}
}
}
You use i in the control expression of the outer for loop but in the inner loop you are modifying i with the i=i/10;.
Even a single execution of that line will ensure that the value of i is lesser than its initial value.
Then this modified i is incremented with the i++ in the outer for loop.
If a is less than b, i<b will always be true, resulting in an infinite loop.
But since you have the number in the form of string in word, you could use that.
for(j=0;j<temp;j++)
{
int c=word[j]-48;
The -48 is used to convert the encoded character value (eg: 2 in ASCII is 50) to the actual number. If the encoding you use is not ASCII, you might have to do something different.
You could also make a copy of i before entering the inner loop and use that variable instead of i in the inner loop like
int t=i, j;
for(sum=j=0;j<temp;j++)
{
int c=t%10;
sum+=pow(c,temp);
t=t/10;
}
You are not resetting the value of sum to 0 before each iteration of the inner loop. You could do that in the first part of the loop (ie, before the first semi-colon) as in the above loop.
Also as pointed out by Bo, pow() returns a float and due to reasons expounded here, inaccuracies might creep in.
So make the type of sum to be float instead of int.
Use of void as the return type of main() is not considered good practice. Use int main() instead. See here.
The part where you take the digits using % operator is also a mistake.
int c=i%10;
On all iterations of the inner loop, value of c would be the last digit of i and you won't get any other digit in c.
I cannot get the following code to work.
#include <stdio.h>
// I am not sure whethere I should void here or not.
int main() {
// when the first bug is solved, I put here arg[0]. It should be
// similar command line parameter as args[0] in Java.
int a=3;
int b;
b = factorial(a);
// bug seems to be here, since the %1i seems to work only in fprintf
printf("%1i", b);
return 0;
}
int factorial(int x) {
int i;
for(i=1; i<x; i++)
x *= i;
return x;
}
How can you get the code to work?
You're modifying your loop terminating variable (x) inside the loop. Currently your code blows up after a few iterations, when x overflows the range of a 32 bit integer and then becomes negative and very large, hence terminating the loop.
It should be:
int factorial(int n) {
int i, x = 1;
for (i = 2; i <= n; ++i) {
x *= i;
}
return x;
}
Better yet, you should use long instead of int for the variable x and the return value, because n! gets very large very quickly.
AInitak gave the right answer, but I want to add that one way you can find the bug in your code is to print out the values of i and x in the factorial loop.
int factorial(int x) {
int i;
for(i=1; i<x; i++)
{
x *= i;
printf("%d, %d\n", i, x);
}
return x;
}
This gives you the output
1, 3
2, 6
3, 18
4, 72
5, 360
6, 2160
7, 15120
8, 120960
9, 1088640
10, 10886400
11, 119750400
12, 1437004800
13, 1501193216
14, -458131456
-458131456
This makes it easier to see what's going wrong. The loop doesn't stop where you expect it to for the reasons AInitak explained.
It's bad style in C to leave out void when defining or declaring a function. So put it in
int main(void)
While it doesn't change anything about the number of parameters the function has (the function has zero parameters without that void either), it will declare the function as one that accepts only zero arguments, while it won't tell anything about the amount and types of accepted arguments when you omit the void. However, both versions with and without void are correct.
Read this answer about that matter too.
#include<stdio.h>
#include<stdlib.h>
int main(int c,char *v[])
{
int x,y;
int *num;
if(c==1)
{
printf("Usage : programName : number");
return 0;
}
num=(int *)malloc(sizeof(int));
*num=atoi(v[1]);
x=1;y=1;
while(x<=*num)
{
y=y*x;
x++;
}
printf("Factorial of %d is %d ",*num,y);
free(num);
return 0;
}
What error message do you get?
First off, declare your function factorial before main. Also, pay attention to correct indentation. Your declaration of function main is correct, by the way.
I would suggest to use also double or unsigned long for factorial computation in order to be able to compute the greater value of the factorial function.
double fact( double n)
{
if ( n == 1)
return 1;
return n*(fact(n-1));
}
A more elegant non-recursive function.
#include<stdio.h>
long long int fact(long long int);
long long int fact(long long int n){
long long int num = 1;
long long int fi = 0;
for(long long int i=2;i<=n;i++){
for(long long int j=1;j<=i;j++){
fi += num;
}
num = fi;
fi = 0;
}
return num;
}
int main(){
long long int n;
scanf("%lld",&n);
printf("%lld\n",fact(n));
return 0;
}