C can't find 10th decimal digit of sqrt{2} - c

My code for finding 10th decimal digit of square root of 2.
#include <stdio.h>
unsigned long long int power(int a, int b);
unsigned long long int root(int a);
int main()
{
int n;
n=10;
printf("%llu \n",root(n));
return 0;
}
unsigned long long int power(int a, int b)
{
int i;
unsigned long long int m=1;
for (i=1;i<=b;i++)
{
m*=a;
}
return m;
}
unsigned long long int root(int a)
{
unsigned long long int c=1;
int counter=1;
while(counter<=a)
{
c*=10;
while(power(c,2)<=2*power(10,2*counter))
{
c++;
}
c-=1;
counter++;
}
return c;
}
I have tried the same algorithm in python. It can find the 10th decimal digit of $sqrt{2}$ immediately.
However, while doing C, I have waited for 10 mins but without a result.

Python handles big numbers for you. [1]
Although, as you say that you are getting the answer "immediately", your algorithm in python is not probably the same as the one you used in C.
#bruno's answer already explains why you are not getting the expected results in C.
[1] Handling very large numbers in Python

Exceed the range that the data can represent. when counter is equal to 10,2*power(10,2*counter) exceeds the range that unsigned long long int can represent. Python supports large number calculations, unlimited digits

you have overflow(s)
when counter values 10 you try to compute power(10,20) but even long long on 64 bits are not enough large, so you loop in
while(power(c,2)<=2*power(10,2*counter)){
c++;
}
for a long time (may be without ending)
Having long long on 64 bits allows to compute the result for n valuing up to 9

Related

Why am i not able to print 47th fibonacci number correctly?

I am using 64 bit operating system ,then also i am not able to print 46th fibonacci number correctly which is less than 4 billion.
#include<cs50.h>
#include<stdio.h>
int main(void)
{
unsigned int n=50;
int array[n];
array[0]=0;
array[1]=1;
printf("%i\n",array[0]);
printf("%i\n",array[1]);
for(int i=2;i<n;i++)
{
array[i]=array[i-1]+array[i-2];
printf("%i\n",array[i]);
}
You have to use long long as your data type of the array. because You are going to store out-range numbers of the integer range.(-2,147,483,648 to 2,147,483,647)
And declaration of int i should be before the for loop.
#include<stdio.h>
int main(void)
{
int n=50;
long long array[n];
array[0]=0;
array[1]=1;
printf("%lli\n",array[0]);
printf("%lli\n",array[1]);
int i;
for(i=2;i<n;i++)
{
array[i]=array[i-1]+array[i-2];
printf("%lli\n",array[i]);
}
}
i am not able to print 46th fibonacci number correctly which is less than 4 billion.
You are most probably going out of range of an integer, which is from -4294967296 to 4294967295.
Change int array[n]; to long long array[n];
Also, the printf's should be changed from %i to %lli
Edit : On running the numbers, you get expected value of F(48) as 4807526976 which is out of range of an integer.
Using Rishikesh Raje's counting system (i.e. 1st Fibonacci is 1) where F(48) is 4807526976, then you weren't able to get F(47) 2971215073 because, as #kaylum commented, you used a signed integer array to hold your values which you need to change to unsigned, and well as change your printf statement to print an unsigned. This would allow you to reach the limit of 32 bit arithmetic:
#include <stdio.h>
#define LIMIT (50)
int main(void) {
unsigned int array[LIMIT] = {0, 1};
printf("%u\n", array[0]);
printf("%u\n", array[1]);
for (size_t i = 2; i < LIMIT; i++)
{
array[i] = array[i - 1] + array[i - 2];
printf("%u\n", array[i]);
}
return 0;
}
To get beyond 32 bits, you can switch to long, or long longs as Rishikesh Raje suggests, but work with unsigned variants if you want to reach the maximum result you can with a given number of bits.
Either Use an unsigned integer array or for more higher values use unsigned long long long array but you don't need an array to print fibonacci series you can simply do this:-
void main()
{
unsigned long long i=1, num1=1, num2=0;
printf("1 \n");
for(i; i<100 ; i++)
{
num1=num1+num2;
num2=num1-num2;
printf("%lli \n", num1);
}
getch();
}

C segfault using long integers

I don't understand why this code compiles and then segfaults:
#include <stdio.h>
#include <stdlib.h>
unsigned long int gcd(unsigned long int, unsigned long int);
unsigned long int lcm(unsigned long int, unsigned long int);
int main(int argc, char *argv[]) {
int i;
unsigned long int n = 1L;
for (i = 2; i < 21; i++) {
n = lcm(n, i);
}
printf("%ld\n", n);
return 0;
}
unsigned long int gcd(unsigned long int a, unsigned long int b) {
if (a == b) return a;
if (a > b) return gcd(a - b, b);
return gcd(a, b - a);
}
unsigned long int lcm(unsigned long int a, unsigned long int b) {
return abs(a * b) / gcd(a, b);
}
Are those unsigned longs even necessary? I also noted that if I change that 21 to a 18 it gives the correct result. The code is meant to find the LCM of all the numbers from 1 to 20.
Running it in gdb gives:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400643 in gcd (a=7536618, b=18) at p5.c:19
19 if (a > b) return gcd(a - b, b);
You're overflowing the stack. Which is a shame, because that should be easily optimized as tail recursion, full recursion is extremely overkill for this. Using the proper optimization levels in any modern compiler (cl, gcc, icc) should get rid of the segfault.
Luckily writing this iteratively is trivial as hell:
unsigned long gcd(unsigned long a, unsigned long b)
{
while(a != b)
if(a > b)
a -= b;
else
b -= a;
return a;
}
Due to how the stack and how they work, there's a limit on how deep function calls can be nested, depending on how much local state they keep.
For extremely imbalanced arguments, implementing gcd by repeated subtraction requires a lot of iterations, and so your recursion goes way to deep. You need to either change the implementation (e.g. make it iterative), or change the algorithm (e.g. compute remainders instead of differences).
You could increase the stack size, but that is wasteful of memory and the larger size will run eventually run out too with larger inputs.

Sum of multiple float points number

I write a algorithm to get the sum of float points number, and this algorithm works perfect for integer but when I applied to float points, the sum I got is a negative number. however my array of float points does only have positive float points number. here I post my code, thank you for checking it.
static unsigned int do_heap_sum(double ary[], unsigned int n,
double *result)
{
unsigned int j;
int counter=0;
double sum=0;
double min;
while(n>counter){
make_heap(ary,n);
min=ary[0];
sum=sum+min;
for(j=1;j<n;j++){
ary[j-1]=ary[j];
}
counter=counter+1;
}
*result=sum;
//exit(EXIT_FAILURE);
return 0;
}
in this code, I use the make_heap to find the min. do you think this has problem? (this make_heap works perfectly with integers extracting the min of array).
thanks again.
In your code, you want to calculate sum of the heap which stored in double[], so make_heap is superfluous, a simple loop is enough.
Make sure double is big enough to save the sum.
For ary[j-1] = ary[j] in for(j=1;j<n;j++), why not just swap ary[0] and ary[n - counter - 1] then adjust the heap in next loop, it's much cheaper.
My wild guess is that you used an integer version of make_heap:
void make_heap(int *ary,size_t n);
instead of a double precision float version:
void make_double_heap(double *ary,size_t n);
Otherwise, I notice that you sort a heap of size n, n times: that's too much work. What happens when some elements of ary are duplicated ?
You could rewrite the loop:
static unsigned int do_heap_sum(double ary[], unsigned int n,
double *result)
{
unsigned int counter=0;
double sum=0;
double min;
while(n>counter){
make_double_heap(ary+counter,n-counter);
min=ary[counter];
sum=sum+min;
counter=counter+1;
}
*result=sum;
return 0;
}

C program : crashes for values greater than 0.3 million [duplicate]

This question already has answers here:
Big array gives segmentation error in C
(4 answers)
Closed 9 years ago.
This program is to find the prime number which is is the sum of most number of consecutive prime numbers. When I set the value of LIMIT to 50 100 or even 1000, the correct values are obtained. But if I take the value of LIMIT greater than 0.3 million the program crashes. What is the reason behind this problem and how can I solve it?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define LIMIT 300000
//binary search function
int Bsearch(long long int *arr,long long int low,long long int high,long long int search)
{
if(high<low)
return 0;
long long int mid = (low+high)/2;
if(search<arr[mid])
{return(Bsearch(arr,low,mid-1,search));}
else if(search>arr[mid])
{return(Bsearch(arr,mid+1,high,search));}
else if(search==arr[mid]) return 1;
else return 0;
}
int main()
{
long int arr[LIMIT];
arr[0]=0;arr[1]=1;
for(long long int i=2;i<=LIMIT;i++)
{arr[i]=1;}
long long index=2;
for(long long int i=3;i<=LIMIT;i++,index++)
{
for(long long int j=2;j<=sqrt(i);j++)
{
if(i%j==0)
{arr[index]=0;}
}
}
long long int count=0;
//calculate total primes
for(long int A=0;A<LIMIT;A++)
{
if(arr[A]==1)
count++;
}
//all primes stored in seperate primes array
long long int primes[count];
for(long int A=0,index=0;A<LIMIT;A++)
{
if(arr[A]==1)
{
primes[index++]=A+1;
}
}
long long int primes_sum[count];
primes_sum[0]=primes[0];
for(long long int B=1;B<count;B++)
{primes_sum[B]=primes_sum[B-1]+primes[B];}
for(long long int i =0;i<(sizeof(primes)/sizeof(long long int));i++)
{
printf("\nprime number : %lld\tprimes_sum : %lld",primes[i],primes_sum[i]);
}
struct ultimata
{
long long int num_of_primes;
long long int prime_number;
}final;
final.num_of_primes=0;final.prime_number=0;
for(long long int j=(sizeof(primes_sum)/sizeof(long long int))-1;j>=2;j--)
{
for(long long int i=j-2;i>=1;i--)
{
long long int search_term = primes_sum[j]-primes_sum[i];
printf("\nsearch term : %lld (primes_sum[%lld]-primes_sum[%lld])",search_term,j,i);
if(search_term>LIMIT)
break;
if(Bsearch(primes,0,(sizeof(primes)/sizeof(long long int)),search_term))
{
printf("\nfound! : %lld terms : %lld",search_term,j-i-1);
if((j-i-1)>final.num_of_primes)
{
printf("\nfound! : %lld",search_term);
final.prime_number=search_term;
final.num_of_primes=j-i-1;
}
}
}
}
printf("Largest prime number : %lld",final.prime_number,final.num_of_primes);
return 0;
}
I think one of your problems is in these lines (multiple times in other places, too):
long int arr[LIMIT];
...
for(long long int i=2;i<=LIMIT;i++)
{arr[i]=1;}
Your array has LIMIT entries, but you try to write to entry LIMIT+1. C starts with array index 0 and ends with size-1.
I don't know why it works for smaller values of LIMIT.

Write a program to find the sum of positive odd numbers and the product of positive even numbers less than or equal to 30

I am having some problems with writing a C program for this question. Maybe am reading the question wrong and doing it the wrong way. Could someone help me with it please? This is they way I'm trying to do it
#include<stdio.h>
void main(void)
{
int j, sum=0;
long int product=1;
for(j=1;j<=30;j=j+2)
{
sum=sum+j;
}
for(j=2;j<=30;j=j+2)
{
product=product*j;
}
printf("\nThe sum of positive odd numbers is: %d", sum);
printf("\nThe product of positive even numbers is: %d", product);
}
The output I am getting is:
The sum of positive odd numbers is: 225
The product of positive even numbers is: -1409286144
I am getting the product part wrong. I have tried using unsigned long int, long long, unsigned long long. Nothing works.
Try using %ld instead of %d in your printf:
printf("\nThe product of positive even numbers is: %ld", product);
Since it's a long int and not an int.
If you use long long int, you'd want %lld. You might need the long long size, given that this is a very very large product. I don't know if your platform's long int is 32 or 64 bit, but you will certainly need a 64 bit number here.
The long long format string can vary depending on your exact platform and compiler, but mostly things have standardized on %lld nowadays. In particular, old Microsoft compilers sometimes used %I64d.
There are no issues as far as the sum of all odd numbers less than 30 is concerned as it's only 225.But the product of all even numbers (or odd numbers for that matter) less than 30 is an enormous number.For that you need a data type with larger capacity.In the following program I have simply used double instead of long int for product and I have used the %e format specifier to display the product in prinf() in a neat way, though you can use %f as well.
#include<stdio.h>
int main(void) //Return type of main() is "int",not "void" as you've used
{
int j, sum=0;
double product=1; //Change type of "product" to "double"
for(j=1;j<=30;j=j+2)
{
sum=sum+j;
}
for(j=2;j<=30;j=j+2)
{
product=product*j;
}
printf("The sum of positive odd numbers is: %d\n", sum);
printf("The product of positive even numbers is: %e",product); //Use %e
}
Output
The sum of positive odd numbers is: 225
The product of positive even numbers is: 4.284987e+16
calculate use unsinged int (32bit)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef unsigned short UInt16;
typedef unsigned UInt32;
typedef struct _unums {
size_t size;
UInt16 *nums;//array
} UNums;
void UNums_init(UNums *num, UInt16 n){
num->nums = malloc(sizeof(UInt16));
num->nums[0] = n;
num->size = 1;
}
void UNums_mul(UNums *num, UInt16 n){
UInt16 carry = 0;
size_t i;
for(i=0;i<num->size;++i){
UInt32 wk = n;
wk = wk * num->nums[i] + carry;
num->nums[i] = wk % 10000;
carry = wk / 10000;
}
if(carry){
num->size += 1;
num->nums = realloc(num->nums, num->size * sizeof(UInt16));
num->nums[i] = carry;
}
}
void UNums_print(UNums *num){
size_t i = num->size;
int w = 0;
do{
--i;
printf("%0*hu", w, num->nums[i]);
if(!w) w = 4;
}while(i!=0);
}
void UNum_drop(UNums *num){
free(num->nums);
num->nums = NULL;
}
int main( void ){
UNums n;
UInt16 i;
assert(sizeof(UInt32) == 4);//32bit
assert(sizeof(UInt16) == 2);//16bit
UNums_init(&n, 1);
for(i=2;i<=30;i+=2)
UNums_mul(&n, i);
UNums_print(&n);//42849873690624000
UNum_drop(&n);
return 0;
}

Resources