Why this function in c is giving unexpected results? - c

I'm learning C function construction and I'm trying to make an exponent function with two arguments: base & exponent.
#include <stdio.h>
#include <stdlib.h>
int power(int a,int b){
int c;
int i;
c=1;
for(i=1;i<=b;++i){
c=c*a;
}
return c;
}
int main(){
int nice=power(5,20);
printf("answer =%d , and size is=%d ", nice, sizeof(nice));
return 0;
}
When I execute the program, it gives me the following output:
answer =1977800241 ,and size is=4
EDIT:
But when I execute power(5,2), it gives a perfect result of 25.

It is having integer overflow. You have to use unsigned long long or long long .
#include <stdio.h>
#include <stdlib.h>
typedef long long ll;
ll power(ll a,ll b){
ll c,i;
c=1;
for(i=1;i<=b;++i){
c=c*a;
}
return c;
}
int main(){
ll nice=power(5,20);
printf("answer =%lld , and size is=%lld ", nice, sizeof(nice));
return 0;
}
NOTE:
You will have a good idea about this -> read this SO question.
QUESTION-2: WHat happens for a=5 b=100
Then you have to write your custom function for manipulating the multiplications. Use int arr[100] to hold the digits of the large number and then multiply it accordingly.C/C++ doesn't provide anything like BIgInt of Java, you have to build it.

Related

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

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

How to store individual units of an int in an int array; C Language

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;
}

Riemann Zeta function in C for negative's odd reals

I'm trying to code the Riemann Zeta function in C but I'm having quite issues with the negative odds one. Since Even negatives are 0 by definition. Only for Real numbers the function, not complex. So 0..1 it's undefined. I know it's some math error I'm doing, but I started today to read about this function and I'm trying to learn.
https://en.wikipedia.org/wiki/Riemann_zeta_function
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double zeta(double s, long long int n)
{
double p=0.0;
if(s<0 && fmod(s,2)==0)
{
return p;
}
if(s==0) { return -0.5;}
if(s>0 && s<=1)
{
puts("Undefined. ");
exit(-1);
}
long long int i;
for(i=n; i>0; i--)
{
p+=pow(i,-s);
}
return p;
}
int main()
{
double s;
puts("Enter real number to Zeta function: ");
scanf("%lf",&s);
printf("\n%.15lf",zeta(s,1000000));
return 0;
}
It's just a sketch... Nothing professional here!
example: zeta(-5) = -0.003968253968253
it's giving 1.036927755143338...
I'm only having issues with NEGATIVE REAL ones...
I'm on Windows 10, Codeblocks with GCC.
The code was update with the #NPE contributions but still not working for negative real odds...
I did not participate in comments, sorry.
following the definition of the zeta-function the simple way of coding is (I just changed s to -s from your code, and added the 'level of convergence n' as a parameter)
double zeta_simple(double s, long long int n)
{
double p=0.0;
long long int i;
for(i=1; i<=n; i++)
{
p+=pow(i,-s);
}
return p;
}
However the problem is that you start adding the "big" numbers before the "small" and soon you will hit underflow operation. So what you want to do is
double zeta(double s, long long int n)
{
double p=0.0;
long long int i;
for(i=n; i>0; i--)
{
p+=pow(i,-s);
}
return p;
}
you can test convergence with s=2 which converges to PI^2/6.0 and s=4 which converges to PI^4/90.0
#define PI 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679L
int main()
{
long long int n;
for (long long int n=10; n<=100000000; n*=10)
{
printf("%28.16f\t %28.16f\n", zeta(4.0, n), zeta2(4.0, n));
}
printf("%s=%20.16f\n\n","PI^4/90", PI*PI*PI*PI/90.0);
for (long long int n=10; n<=10000000000; n*=10)
{
printf("%28.16f\t %28.16f\n", zeta(2.0, n), zeta2(2.0, n));
}
printf("%s=%20.16f\n","PI^2/6 ", PI*PI/6.0);
}
you get
1.0820365834937564 1.0820365834937566
1.0823229053444732 1.0823229053444725
1.0823232333783044 1.0823232333783073
1.0823232337108049 1.0823232337108359
1.0823232337111379 1.0823232337109849
1.0823232337111381 1.0823232337109849
1.0823232337111381 1.0823232337109849
1.0823232337111381 1.0823232337109849
PI^4/90= 1.0823232337111379
1.5497677311665408 1.5497677311665408
1.6349839001848929 1.6349839001848925
1.6439345666815597 1.6439345666815606
1.6448340718480596 1.6448340718480665
1.6449240668982261 1.6449240668982523
1.6449330668487265 1.6449330668487985
1.6449339668482315 1.6449339668477756
1.6449340568482265 1.6449340573291047
1.6449340658482263 1.6449340600880324
1.6449340667482264 1.6449340600880324
PI^2/6 = 1.6449340668482264
see how the convergence of zeta_simple stops after a while... For convergence to continue you have to use zeta
You can also see that for 10000000000 operations (hence the use of long long int) you only get a precision on 9 digits for s=2. And as s increase so does the rate of convergence.
Therefore for small s to be efficient people use accelerated convergence formulae.
If you want to dig further I recommend you look at https://math.stackexchange.com/questions/183680/modern-formula-for-calculating-riemann-zeta-function
Also wat is really interesting is when you start poking around with s complex

Adding Two numbers with using only one variable in C

I was trying to create a program that inputs two number and outputs their sum. For this I must have to use two variables. I was just curious whether this can be done by using only one variable.
Note : user has to input two numbers.
#include<stdio.h>
int main()
{
int a, b;
scanf("%d%d",&a,&b);
printf("%d",(a+b));
return 0;
}
#include <stdio.h>
int main ( void )
{
int a[3];
scanf("%d", &a[0]); /* first number */
sscanf("%d", &a[1] ); /* second number */
a[2] = a[0] + a[1];
printf("sum is %d\n", a[0] + a[1] );
printf("sum stored in a[%d] is %d\n", 2, a[2] );
return 0;
}
Technically one variable, a pointer:
#include<stdio.h>
int main() {
int *nums = malloc(2 * sizeof(int));
scanf("%d%d",nums, (nums + sizeof(int)));
printf("%d",(*nums + *(nums + sizeof(int))));
return 0;
}
But no there isn't really an elegant way to use one variable for two inputs.
Note that I've considered the question like a challenge or a puzzle. Do not consider this answer good C practice. Obviously the cleanest way to make a sum of 2 values from input is to use 2 variables. I still find the challenge interesting though.
#include <stdio.h>
#include <math.h>
int main()
{
int a;
printf("%g", fmin((scanf("%d", &a), a), 1.0/0.0 + rand()) + fmin((scanf("%d", &a), a), 1.0/0.0 + rand()));
return 0;
}
Works with negative values.
I'm using the comma operator which executes both expressions but only return the second one. So (scanf("%d", &a), a) is like calling scanf("%d", &a) and returns a. I pass this result through a function (any function) as I want to prevent updating the value (to sum it with the new a). I have no idea if your compiler will call the left or right part of the big expression first but it doesn't matter as both are doing the same thing. Whichever executes first will be the first value from input.
fmin(x, 1.0/0.0 + rand()) makes sure nothing is inlined by the compiler. 1.0/0.0 is Infinity and would never be returned in fmin() in our case. Compiler would inline this to x normally but adding + rand() to Infinity (which is still Infinity) seems to prevent it.
You can even do it by declaring "0" variable by using argc:
#include <stdio.h>
#include <math.h>
int main(int a)
{
printf("%g", fmin((scanf("%d", &a), a), 1.0/0.0 + rand()) + fmin((scanf("%d", &a), a), 1.0/0.0 + rand()));
return 0;
}
I've used this to test: https://www.onlinegdb.com/online_c_compiler
Adding Two numbers with using only one variable in C
Create a helper function with the 1 variable.
#include <stdio.h>
int scan_int(void) {
int a;
if (scanf("%d", &a) == 1) {
return a;
}
return 0;
}
int main(void) {
printf("Sum %d\n", scan_int() + scan_int());
return 0;
}
Note that scan_int() + scan_int(), code could call either the left or the right scan_int() first (or in parallel). Fortunately + is commutative, so it makes no difference here.
The "trick" here is that there exist in sequence or in parallel, a 1st_call_scan_int::a and 2nd_call_scan_int::a. Still only one variable in code.
OK, there's been quite a few interesting answers, but weirdly nobody has thought of the obvious way to store 2 ints in a single variable - structs:
#include<stdio.h>
typedef _in struct {
a int
b int
} inp;
int main(void)
{
inp input;
scanf("%d%d",&input.a,&input.b);
printf("%d",input.a+input.b);
return 0;
}
int main(void) {
int *num = malloc(sizeof(int)*2);
scanf("%d %d", num, num+1);
printf("%d\n", num[0] + (num[1]));
}
int *num = malloc(sizeof(int)*2); //two int space
scanf("%d %d", num, num+1); // num (pos 0), num+1 (pos1)
printf("%d\n", num[0] + (num[1])); //the sum of the positions
Only one variable - no tricks. As many numbers can be added as you want :)
#include <stdio.h>
int ScanAndAdd(void)
{
int a;
if(scanf("%d", &a) != 1) return 0;
return a + ScanAndAdd();
}
int main()
{
printf("%d\n", ScanAndAdd());
return 0; /**/
}
One way to do it is.
#include <stdio.h>
int x;
int enter(){
scanf("%d",&x);
return x;
}
int main()
{
x=enter()+enter();
print("sum of two number is %d",x);
return 0;
}
Another way to do it..
#include <stdio.h>
int main()
{
int x;
scanf("%d",&x);
printf("next no. ");
x= x*(scanf("%d",&x))+x;
printf("%d",x);
return 0;
}
Although the second one is not consistent, in some compiler it works perfectly and in some, it doesn't
#include <stdio.h>
int main()
{
long long int buffer=0;
scanf("%d",(int*)&buffer);
scanf("%d",(int *)&buffer+1);
printf("\nsum is %d\n",*((int*)&buffer)+*((int*)&buffer+1));
return 0;
}
Try this on for size. It uses fixed width C99 types to guarantee that memory alignment works as intended. It even does the 32-bit arithmetic in a uint64_t type to prevent overflow issues. This will work with any of the other fixed-width integer types, signed or unsigned, with trivial modification.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main (void)
{
uint64_t a;
scanf ("%" SCNu32 "%" SCNu32, (uint32_t*)&a, (uint32_t*)&a + 1);
printf ("%" PRIu64 "\n", (uint64_t)((uint32_t*)&a)[0] +
((uint32_t*)&a)[1]);
}
The above code was modified from my original answer, seen below. I removed the void* cast in (uint32_t*)(void*)&a because it was unnecessary. I also cleaned up the scanf arguments to increase readability, and added a new line to the end of the printf format argument.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main (void)
{
uint64_t a;
scanf ("%" SCNu32 "%" SCNu32,
&((uint32_t*)(void*)&a)[0], &((uint32_t*)(void*)&a)[1]);
printf ("%" PRIu64, (uint64_t)((uint32_t*)(void*)&a)[0] +
((uint32_t*)(void*)&a)[1]);
}

Function returning a 2d-array-- abort trap 6

I'm writing a simple program taking a double alpha and integer deg that prints a matrix mat as computed by create_basis. Below is the code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 30
void create_basis(uint64_t mat[][MAX],double alpha, int deg);
void create_basis(uint64_t mat[][MAX],double alpha,int deg){
int i;
int j;
for(i=0;i<deg+1;i++){
for(j=0;j<deg+2;j++)
mat[i][j]=0;
}
for(i=0;i<deg+1;i++){
mat[i][deg+1]=floor(pow(alpha,i)*pow(10,16));
mat[i][i]=1;
}
}
int main(){
int deg;
double alpha;
int i;
int j;
printf("Enter number:\n");
scanf("%lf",&alpha);
printf("Enter degree:\n");
scanf("%d",&deg);
uint64_t mat[deg+1][deg+2];
create_basis(mat,alpha,deg);
printf("Matrix basis=\n\n");
for(i=0;i<deg+1;i++){
for(j=0;j<deg+2;j++){
if(j==0)
printf("[%llu ",mat[i][j]);
if(j==deg+1)
printf("%llu]",mat[i][j]);
else
printf("%llu ",mat[i][j]);
}
printf("\n");
}
return 0;
}
However, when I run, there seems to be an issue when I call create_basis in main because it is giving an abort trap 6 error, which I presume to mean I'm trying to access memory I don't have. However, the dimensions of mat seem to agree with what I'm trying to access. Am I calling create_basis incorrectly? Any ideas are greatly appreciated!
void create_basis(uint64_t mat[][MAX],double alpha,int deg){
change to
void create_basis(int deg, uint64_t mat[deg+1][deg+2],double alpha){
As reasons already explained #SteveSummit is
Two-dimensional array does not have to match.

Resources