Recently I have been coding in C and I was trying to solve a number swapping problem. I have done it the easier way, by using a temporary variable. But my instructor told me use another method without temp variable. This is my code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a,b,temp;
printf("Enter two numbers: ");
scanf("%d%d",&a,&b);
printf("Entered Numbers:%d,%d \n",a,b);
temp = a; //This method is the easiest one.
a = b;
b = temp;
printf("Numbers are swapped as: %d,%d \n",a,temp);
a = (a*b)/a;
b = (a*b)/b;
printf("Numbers are swapped as: %d,%d",a,b);
return EXIT_SUCCESS;
}
I got the output as follows:
Enter two numbers: 50 32
Entered Numbers:50,32
Numbers swapped with temp are: 32,50
Numbers swapped without temp are: 50,50
Can anyone guess what might be the error? I believe my math is right, but why is it showing like this?
You have made a silly mistake in your second logic, just replace with mentioned one:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a,b,temp;
printf("Enter two numbers: ");
scanf("%d%d",&a,&b);
printf("Entered Numbers:%d,%d \n",a,b);
temp = a; //This method is the easiest one.
a = b;
b = temp;
printf("Numbers are swapped as: %d,%d \n",a,temp);
a = a * b; //Change 1
b = a / b; //Change 2
a = a / b; //Change 3
printf("Numbers are swapped as: %d,%d",a,b);
return EXIT_SUCCESS;
}
You made a mistake in the swapping code: the multiplication method uses 3 steps:
compute the product a * b into a
divide a by b into b, effectively setting b to the original value of a.
divide a by b into a, effectively dividing the product by the original value of a, hence setting a to the original value of b.
The problem with this approach is it does not work for many cases:
if b is zero, the first division has undefined behavior, crashing the program in many cases
if a is zero, the second division has undefined behavior.
if a * b exceeds the range of type int, you also have undefined behavior, producing incorrect results or even a crash (try swapping 65536 and 65536).
There is another method without a temporary variable the is much safer and reliable: instead of multiplying the numbers and dividing the product, you can xor the numbers and use xor again to retrieve the original values and swap them.
Note also that your third printf statement is incorrect: you print the value of temp instead of b.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int main() {
int a, b, temp;
printf("Enter two numbers: ");
if (scanf("%d%d", &a, &b) != 2)
return EXIT_FAILURE;
printf("Entered Numbers: %d,%d\n", a, b);
temp = a; //This method is the easiest one.
a = b;
b = temp;
printf("Numbers are swapped with temp as: %d,%d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("Numbers are swapped with xor as: %d,%d\n", a, b);
a = a * b;
b = a / b;
a = a / b;
printf("Numbers are swapped with multiplication as: %d,%d\n", a, b);
return EXIT_SUCCESS;
}
Sample runs without optimisations:
Enter two numbers: 12 42
Entered Numbers: 12,42
Numbers are swapped with temp as: 42,12
Numbers are swapped with xor as: 12,42
Numbers are swapped with multiplication as: 42,12
Enter two numbers: 1 0
Entered Numbers: 1,0
Numbers are swapped with temp as: 0,1
Numbers are swapped with xor as: 1,0
Floating point exception: 8
Enter two numbers: 65536 65536
Entered Numbers: 65536,65536
Numbers are swapped with temp as: 65536,65536
Numbers are swapped with xor as: 65536,65536
Floating point exception: 8
The same runs with optimisations (clang or gcc):
Enter two numbers: 12 42
Entered Numbers: 12,42
Numbers are swapped with temp as: 42,12
Numbers are swapped with xor as: 12,42
Numbers are swapped with multiplication as: 42,12
Enter two numbers: 1 0
Entered Numbers: 1,0
Numbers are swapped with temp as: 0,1
Numbers are swapped with xor as: 1,0
Numbers are swapped with multiplication as: 0,1
Enter two numbers: 65536 65536
Entered Numbers: 65536,65536
Numbers are swapped with temp as: 65536,65536
Numbers are swapped with xor as: 65536,65536
Numbers are swapped with multiplication as: 65536,65536
What is going on? Is the compiler broken? As can be verified with Goldbolt's Compiler Explorer, when optimisations are turned on, both clang and gcc are able to identify the 3 swapping methods and generate the same swapping code with 4 mov instructions. Since the third method has undefined behavior on cases where the multiplication or division would fail, producing any result is OK, including the expected one. A blatant case of undefined behavior abuse. Your instructor should be amazed at this discovery.
Related
I had to make a recursive function that use only multiplication operation to get the answer of X in power of N.
I wrote this:
#include <stdio.h>
int power(int x, int n);
int main()
{
int x, n;
printf("Enter base and exponent:\n");
scanf("%d%d", &x, &n);
printf("%d\n", power(x, n));
return 0;
}
int power(int x, int n)
{
if (n==0) return 1;
return x*power(x, n*0.5);
}
So its works good for small number, like if the input x=3, n=2 the output will be 9 which is good. But when I input bigger numbers, for example: x=362, n=123 the output will be -79249792 which its wrong.
Can someone help me understand what's wrong?
(Im using Online C Compliler {OnlineGBD})
First, the recursion you implemented shouldn't work for small numbers too, since as others have pointed out, x^n = (x^(n/2))^2 and not x*(x^(n/2)), and for odd values of n, n/2 will get truncated since the function takes integer arguments. Try 2^3, your code gives answer 4. A simple way to fix this is via using the following recursion : x^n = x*(x^(n-1)), or if you want to make the code more efficient, use this algorithm.
But this still doesn't address negative numbers showing up. The problem is max size of int is 2^31-1 = 2,14,74,83,647. This is due the way it is stored in memory, occupying 32 bits. What happens when you cross this limit? It overflows, and becomes -2^31. So you won't be able to get correct answers for big numbers. Generally this is handled by calculating the answer modulo some prime number, or creating arbitrary precision data structures. Check out this and this.
First of all, please remove this:
printf("Enter base and exponent:\n");
scanf("%d%d", &x, &n);
printf("%d\n", power(x, n));
and write a simple, easy to run test harness that doesn't involve thinking and typing input into the console, with clear output of expected/actual values on failure:
#include <math.h>
#include <stdio.h>
int power(int base, int exponent) {
return 1;
}
int main(void) {
for (int base = 0; base < 5; base++) {
for (int exponent = 0; exponent < 5; exponent++) {
int expected = (int)pow(base, exponent);
int actual = power(base, exponent);
if (expected != actual) {
printf("[FAIL] power(%d, %d) was: %d\n"
" expected: %d\n\n",
base, exponent, actual, expected);
}
}
}
return 0;
}
Notice the clearer parameter names on the power function and usage of the built-in pow to ensure correct logic.
Now let's test your algorithm:
[FAIL] power(2, 3) was: 4
expected: 8
[FAIL] power(2, 4) was: 8
expected: 16
[FAIL] power(3, 3) was: 9
expected: 27
[FAIL] power(3, 4) was: 27
expected: 81
[FAIL] power(4, 3) was: 16
expected: 64
[FAIL] power(4, 4) was: 64
expected: 256
It appears that n*0.5 isn't giving the correct reduction factor.
Taking a step back, exponentiation by multiplication is done by repeatedly multiplying base by itself exponent times and accumulating onto a result initialized to 1:
int power(int base, int exponent) {
int result = 1;
for (int i = 0; i < exponent; i++) {
result *= base;
}
return result;
}
Since we're forced to use recursion, the problem reduces to simulating the classic counting loop above with recursion.
This can be done by subtracting 1 from the exponent per call until we reach 0 (<= 0 is a safer base case than == 0, avoiding blowing the stack on negative input).
As for the return value, you're correct in returning 1 for n == 0 and multiplying base on each frame by the child's value, which is the same as the *= operation in the iterative version.
Here's the fixed code:
int power(int base, int exponent) {
if (exponent <= 0) {
return 1;
}
return base * power(base, exponent - 1);
}
Finally, x=362, n=123 fails because of integer overflow. 362**123 has 315 digits, but 4 byte numbers like int only hold 10-ish. You'll need a big integer library to handle that massive an input.
Note that I haven't attempted to handle negative numbers here. I assume that's out of scope. Making the parameters unsigned would help enforce this contract.
The problem: user inputs two numbers: a big one, and a small one.
The small number is the number of digits from the last digit that will transfer into the front, and the remaining numbers will follow.
For example: if the big number is 456789 and the small one is 3, the result will be: 789456.
my idea was as follows:
if(...) {
newNum = BigNumber%(10*SmallNumber);
printf("%d", remainder");
SmallNumber--;
}
but it doesn't print in the order I was hoping for, digit by digit, and I can't understand why.
If using arrays would be allowed, it was no problem. Also I'm not allowed to use string.length, which also make it lots easier.
Rotating a number can be performed as a combination of cuts, shifts, and additions. For example, if you have a number 123456789 and you need to rotate it by 3, you can do it as follows:
Cut off the last three digits 123456789
Shift the remaining number by three digits to make 123456789
Shift the last three digits by six to make 789000000
Add the two numbers together 789000000 + 123456 to get the result 789123456.
Here is how you do these operations on decimal numbers:
Cutting off the last k digits is done with modulo % 10k
Shifting right by k digits is equivalent to integer division by 10k
Shifting left by k digits is equivalent to multiplication by 10k
Figuring out the number of significant digits in a number can be done by repeated integer division by ten.
Addition is done the usual way.
I think below code would help you -
//Here size = number of digits in bignumber-1
while(smallnumber--) {
temp = (bignumber - bignumber%pow(10,size))/(pow(10,size);
bignumber = bignumber%pow(10,size);
bignumber = bignumber*10 + temp;
}
Try this version:
#include <stdio.h>
#include <math.h>
int main(void)
{
long int num = 34234239;
int swap = 5, other;
long int rem = num % (int)(pow(10,swap)); /*The part that is shifted*/
other = log10(num-rem)+1-swap; /*Length of the other part*/
/* Result = (part to shift)*(Other part's length) + (Other part)*(Shifts) */
num = rem*(int)pow(10,other) + (num-rem)/(int)pow(10,swap);
printf("%ld\n",num);
return 0;
}
I have an array of integer element range up to 10^5, and I have to find the first element after the total multiplication.
Example:
Array : 2,4,6,7
multiplication result: 336 and the first element is 3.
Obviously I cannot multiply the elements with the range up to 10^5.
How can I track only the first digit during multiplication?
We can also find the first digit with another method.
Suppose p be the final value after multiplying all the elements.
So, we have to find
P = a[0]*a[1]*a[2]*a[3]*.......*a[n-1]
for n sized array then we can take log with base 10 on both the side after that our expression changes to
log(p) = log(a[i])+log(a[1])+log(a[2])+.....+log(a[n-1])
Now, to find the first digit we have to get the fractional part of this variable sum which can be done in this way
frac = sum - (integer)sum
and at the last step calculate the 10^frac and convert it to the integer value which is our required first digit.
This algorithm is better in comparison to time complexity.
int getFirstDigit(long a[], long n) {
double p;
for(int i=0;i<n;i++) {
p = p+log10(a[i]);
}
double frac = p - (long)p;
int firdig = (int)pow(10,frac);
return firdig;
}
In c or c++ make integer data type as long double such that first digit of number is before decimal point and rest are after decimal point.
Above can be done as follows:-
long double GetFraction(int number){
int length = (int) log(number) + 1; // this will give number of digits in given number. And log is log base 10.
long double fraction = (long double) number / (10^(length - 1);
return fraction;
}
Example :-
Let number = 12345
length = log(12345) + 1 = 5;
fraction = (long double) 12345 / (10^4) = 1.2345
Now for all integers in array find fraction as mention above and multiply them as follow:-
int GetFirstDigit(int arr[] , int size){
if(size == 0)
return 0;
long double firstDigit = 1.0;
for(int i = 0 ; i < size ; i++){
firstDigit = firstDigit*GetFraction(arr[i]);
if(firstDigit >= 10.00) // You have to shorten your number otherwise it will same as large multiplication and will overflow.
firstDigit/=10;
}
return (int) firstDigit;
}
Disclaimer:- This is my approach and I don't have any formal proof about accuracy of result. But I have verified result for integer up to 10^9 and array size up to 10^5
Please donot forget to note that this is just an attempt to make you understand the logic and that you need to make changes in the code as per your requirement. I strongly suggest you make this a subroutine in your program and parse the arguments to it from the main thread in your program.
#include <stdio.h>
void main()
{
int num1, num2;
printf("Enter ur lovely number:\n");
scanf("%d",&num1);
num2=num1;
while(num2)
{
num2=num2/10;
if(num2!=0)
num1=num2;
}
printf("The first digit of the lovely number is %d !! :P\n ",num1);
}
Try this approach,
Take integer as input let us say int x1, now copy this in a double let us say double x2, and suppose you have previous product as double y, initially y = 1 . now use this loop,
while(x1!<10){
x1 = x1/10;
x2 = x2/10; //this will make double in standard form x*10^y without 10^y part
}
ex x1 = 52, then x2 will be converted to 5.2.
Now let us assume y = 3 and x is 5.2.
then product now is 15.6, again reduce this to 1.56 and repeat the process. in the end you will have the only digit before the decimal as the first digit of the product of all the numbers.
I am writing a program to demonstrate the bisection algorithm(from numerical methods).
What I am doing is this:
defined a function F(int), which takes the integer and returns the value of the polynomial at that integer.
In the bisection() function:
a) a,b are the initial approximations.
b) the for() construct finds the value of a after which the sign(magnitude) of F(a) changes.
c) the printfs are for troubleshooting purposes(except for the last one).
d) int prec is for the precision required for the solution (no. of iterations), where no. of iterations, N=log((b-a)/E), E=10^(-prec).
What I'm getting is this:
Output:
a=1 F(a)=-0.207936
a=1, b=2
Approximation 0: x = 0 a=1072693248 b=1
Approximation 1: x = 0 a=1072693248 b=1
Approximation 2: x = 0 a=1072693248 b=1
Approximation 3: x = 0 a=1072693248 b=1
Approximation 4: x = 0 a=1072693248 b=1
The solution is: x = 1.000000
I have tried commenting the N=... statement and assigning constant integer to N, but to no effect.
Interestingly, commenting out all statements with variable x in the for() construct does not alter values of a and b.
Oddly, if the statement x=(a+b)/2; is commented out, then the value of a is affected by the value with which x is initialized:
i) a=1072693248, when x=1,
ii)when x=0, a=0,b=0
iii)when x=-1, a=-1074790400, b=1
I am using Microsoft Visual C++ 2010 Express for compilation.
Please help me out.
Here is the code:
#include<stdio.h>
#include<math.h>
#define MIN -10
double F(int x)
{
double y=(x*x)-(2*x)+0.792064;
// printf("\nx=%d y=%d",x,y);
return y;
}
void bisection(int prec)
{
int a,b=0;
int c,N=10,i;
double x=0;
for(a=MIN;(F(a)*F(a-1))>0;a++);
printf("\na=%d F(a)=%f",a,F(a));
b=a+1;
printf("\n\na=%d, b=%d",a,b);
N=(log((float)(b-a))+5);
for(i=0;i<N;i++)
{
x=(a+b)/2;
printf("\nApproximation %d: x = %d\ta=%d b=%d",i,x,a,b);
if((F(a)*F(x)>0))
a=x;
else
b=x;
}
printf("\n\nThe solution is: x = %f",x);
getchar();
}
int main()
{
bisection(4);
return 0;
}
It's because a and b are declared as ints. When you write x = (a + b) / 2;, all the elements on the right side are integers, so they will be evaluated to an integer. Moreover, as the difference of a and b is 1, the value would be equal to the smaller one of them, which is a. That's why the value of x becomes 1.0. To fix it, the upper and lower limits should be declared as doubles, not ints. When a and b are integers, their values cannot converge to the actual value of x.
Also, you're using %d in printf to write a double value. It should be %lf.
Is it possible to multiply two numbers with out using arithmetic operators using C? Using the left shift operator, I can multiply any number by 2 only. How about other numbers?
To solve this problem, the first thing you want to do is figure out how to get simple arithmetic operations using just bitwise operators.
For example, addition can be achieved using this technique
int add(int a, int b) {
int c;
while (a != 0) {
c = b & a;
b = b ^ a;
c = c << 1;
a = c;
}
return b;
}
Then it's a matter of doing multiplication using addition:
int mult(int a, int b) {
int i = 0;
int c = 0;
while (i < b) {
c = add(c, a);
i = add(i, 1);
}
return c;
}
This multiplication doesn't yet work if b is negative, but since this looks like a homework problem, I'll leave that as an exercise for you. ;)
Edit:
While multiplication is intuitive once you have addition, the addition function is not so easy to understand, so I'll explain it here.
Let's say you want to add two numbers, 11010011 and 10101. The usual way to do it is to line them up like so:
11010011
+ 10101
You'll notice that when you add two binary numbers, if the ith bit from both numbers is 1, then the resulting bit is 0, and there is a carry over to a bit to the left of i.
This carry is what the variable 'c' in the code stores.
//...
c = b & a;
//...
c << 1;
//...
We bit wise and b and a to get only the bits where both a and b are 1, then we left shift it by 1 to get the carry bits.
Then you can look at the bits where a and b differ, i.e. one of the bits is 1 and the other bit is 0. The resulting bit in this case will be 1 with no carry.
that's what this line stores:
b = b ^ a;
The line above essentially removes the bits where both a and b are 1 (now stored in c).
So now you have another two numbers b and c, that you need to add together.
First let's look at where we're at with the example after the first iteration of the loop
c = a = 00100010
b = 11000110
It might not be entirely obvious yet, but b is accumulating the resulting sum. Through more iterations of the loop, more bits that are carried over are "added" back to b, with carries stored again in c. In that sense, you can think of the xor operator as an addition operation without carry.
Here's the second iteration of that loop:
c = a = 00000010
b = 11100100
3rd iteration:
c = a = 00000000
b = 11100110
Now c (and a) is 0, so there is no more carry to add. We exit the loop and return b. Note that even if you continue the loop, none of the numbers will change.
It is possible, see this wiki for a direction: http://en.wikipedia.org/wiki/Binary_multiplier
void main()
{
int n1, n2, n3, n4, x, y, i;
printf("Enter first number");
scanf("%d", &n1);
printf("Enter second number");
scanf("%d", &n2);
n3 = n2;
n4 = n2;
n1-=1;
for(i = n1;i > 0;i-=1)
{
do {
x = n2 & n3;
y= n2 ^ n3;
n2 = x << 1;
n3 = y;
} while (x);
n2 = y;
n3 = n4;
}
printf("product of two number is %d", y);
getch();
}
Yes it is possible. You can do it with logical operators. After all, that's all that the hardware does when you use an arithmetic operator.