I was writing this code in C when I encountered the following problem.
#include <stdio.h>
int main()
{
int i=2;
int j=3;
int k,l;
float a,b;
k=i/j*j;
l=j/i*i;
a=i/j*j;
b=j/i*i;
printf("%d %d %f %f\n",k,l,a,b);
return 0;
}
Can anyone tell me why the code is returning zero for the first and third variables (k and a)?
Are you asking why k and a show up as zero? This is because in integer division 2/3 = 0 (the fractional part is truncated).
What I think you are experiencing is integer arithmetic. You correctly suppose l and b to be 2, but incorrectly assume that k and a will be 3 because it's the same operation. But it's not, it's integer arithmetic (rather than floating-point arithmetic). So when you do i / j (please consider using some whitespace), 2 / 3 = 0.33333... which is cast to an int and thus becomes 0. Then we multiply by 3 again, and 0 * 3 = 0.
If you change i and j to be floats (or pepper your math with (float) casts), this will do what you expect.
You haven't said what you're getting or what you expect, but in this case it's probably easy to guess. When you do 'a=i/j*j', you're expecting the result to be roughly .2222 (i.e. 2/9), but instead you're getting 0.0. This is because i and j are both int's, so the multiplication and (crucially) division are done in integer math, yielding 0. You assign the result to a float, so that 0 is then converted to 0.0f.
To fix it, convert at least one operand to floating point BEFORE the division: a = (float)i/j*j);
this is due to how the c compiler treats int in divisions:
#include <stdio.h>
int main()
{
int i=2;
int j=3;
int k,l;
float a,b;
k=i/j*j; // k = (2/3)*3=0*3=0
l=j/i*i; // l = (3/2)*2=1*2=2
a=i/j*j; // same as k
b=j/i*i; // same as b
printf("%d %d %f %f/n",k,l,a,b);
return 0;
}
If you're asking why k and a are 0: i/j*j is the same as (i/j)*j. Since j is larger than i, i/j is 0 (integer division). 0*j is still 0, so the result (k) is 0. The same applies to the value of a.
it doesn’t matter if you’re variable is float or not, as long you’re using
integer / integer , you’ll get 0,
but because you’re using a float output, you get 0.0
Related
I am writing a simple C program that prints the sum of the harmonic series like:
1 + 1/2 + 1/3 + ...... + 1/n
My program is:
#include<stdio.h>
void main(){
int n,i;
float num=0, tmp=0;
scanf("%d", &n);
for(i=1;i<=n;i++){
tmp = 1/i;
num = num + tmp;
}
printf("%f", num);
}
As per my understanding, if n=4, the output must be: 2.03333
But the output comes as 1.00000
1/i is not a float value, it is an int of value 0 or 1, because of integer division rules.
The value is 1 for 1/1 otherwise 0. Adding all of them up results in 1.
This is a floating point value:
1.0/i
Adding them up should give the desired result.
To be precise, I should say that 1.0 is a double.
In order to work with actually a float value to match the float variable, use 1.0f. Both are floating point values in contrast to integer values.
As 1 and i are integers, dividing these two will be integer and you will get 0 for i > 1 in this case. You can cast i using (float)i and you will have 1/(float)i.
I have to print product of elements of array A mod 10^9+7,there should N elements in array and the constraints are 1<=N<=10^3 and 1<=A[i]<=10^3.
The code I wrote
#include<stdio.h>
int main()
{
int N, pro = 1;
scanf("%i", &N);
int arr[N];
for (int i = 0; i<N; i++) {
scanf("%i", &arr[i]);
pro = (pro*arr[i]) % (1000000007);
}
printf("%i", pro);
}
gave wrong answer but when I replaced int arr[N] to long int arr[N] and changed its precision specifier to %li it gave correct output.
My confusion is when the upper limit of array's elements is only 10^3 then why using long int worked and not just int.
i am using 64 bit windows OS and the inputs which i am giving are 3 digit numbers
as array elements for example 568,253 etc without any 0 in beginning.
Consider the case where N = 3 and A = [10^3,10^3,10^3].
After the second iteration, your product will be 10^9.
In the third iteration, your product will be (10^9 * 10^3) % 1000000007.
Before doing the modulo operation, the product would create integer overflow and hence the WA.
The problem may be the result of the expression (pro*arr[i]).
If we assume that the maximum value of pro is 1000000006 due to the modulo, and the maximum value of arr[i] is 10^3 as mentioned. So, this expression may take a value greater than a 32bit integer.
The other thing to look for is What the type of (pro * arr[i]) ? :
The compiler answers this question by look to the operands of the expression, and will set the return type, for integer, as the greater type of them.
If you set arr[] as an long int [] this expression will return a long integer, whereas, if you set arr[] as an int, it will return an int and so it'll be wrong :
int * int -> int
int * long int -> long int
This question already has answers here:
Why dividing two integers doesn't get a float? [duplicate]
(7 answers)
Closed 5 years ago.
input example : 356
356/100, is suppused to be 3.56
But I'm getting 3.0000000000, I'm using ideone online compiler for C.
#include <stdio.h>
#include <math.h>
int main() {
int n;
double frac;
scanf("%d", &n);
frac = (n/100);
printf("%lf", frac);
return 0;
}
That's because here frac = (n/100); you are doing plain integer arithmetic (as n is declared as an int and 100 is interpreted as an int (any whole number is taken to be an int unless specified otherwise)). What you need to do is say explicitly that you want to do an arithmetic operation with digits after decimal point. One way is to use a cast: frac = ((double) n/100);
If you don't use the cast, the division will be performed as you expect, but then the digits after the decimal point will be dropped. Since frac is declared as a double, 0s would get tacked on to the end.
In C, the result of division of two integer numbers (e.g. int, short, long) is also an integer (it is counter-intuitive, but it is implemented this way for performance reasons). As a result, the result of 5/2 is 2 and not 2.5. This rule is only for integer numbers. So, if you need to get a floating-point result, at least one of the numbers in a division operation must be of a floating-point type.
In case of your code, if you use 100.0 instead of 100, you will get the desired result. Also you can use casts or define n as double.
This should work:
#include <stdio.h>
#include <math.h>
int main() {
int n; // You can define n as double but don't forget to modify scanf accordingly.
double frac;
scanf("%d", &n);
frac = (n/((double)100)); // Or, frac = (n/100.0)
printf("%lf", frac);
return 0;
}
You cannot call division using integers to be double without declaring it.
For example
int / int will result int.
Try declaring n as double
double n;
scanf("%lf", &n);
frag = n/100;
input data type is an integer.
just change it to double or float to fix this problem.
int main() {
double n;
double frac;
scanf("%d", &n);
frac = (n/100);
printf("%lf", frac);
return 0;
}
I have a small code which does some number transformations. I want to turn a number from double to long and then using right bit shift to cast it to short. But it gives me different results and I don't know why.
I have 3 numbers in an array and I make the sum of them using a for loop and every time I am gonna cast the result to short.
There is a number with .000000007 more exactly 63897600.000000007. Adding this to the total and then subtracting it gives me different results.
I can't figure out why does this occur and how can I manage this particular case.
Here is my code:
#include <stdio.h>
#define DOUBLETOLONG(number) (long)(number)
#define NEAREST(number) ((short)((number + 32768) >> 16))
#define LONGTOSHORT(number) NEAREST(DOUBLETOLONG(number))
int main() {
int k = 0;
double array[3] ={ 41451520.000000, 63897600.000000007, -63897600.000000007 };
double total_x = array[0];
short j = LONGTOSHORT(total_x);
printf("j = %d\n", j);
for (k = 1; k < 3; k++) {
total_x = total_x+array[k];
j = LONGTOSHORT(total_x);
printf("j = %d\n", j);
}
return 0;
}
This are the results:
j = 633
j = 1608
j = 632
41451520 + 63897600 = 105349120
In a double this integer can still be accurately represented. However, we didn't account for the fractional part 0.000000007. Let's check what the next biggest double is:
#include <stdio.h>
#include <math.h>
int main(int argc, char** argv) {
printf("%.23f\n", nextafter(105349120.0, INFINITY));
return 0;
}
Turns out, it's 105349120.000000014901.... Let's put those next to eachother:
105349120.000000014901...
0.000000007
This means that 105349120.000000007 is closer to 105349120 than the next bigger double, so it correctly gets rounded down to 105349120.
However, when we subtract again, 105349120 - 63897600.000000007 gets rounded down, because the next smaller double than 41451520 is (nextafter(41451520.0, 0)) 41451519.999999992549.... Put them next to eachother:
41451519.999999992549...
41451519.999999993
Yep, closer to the first double below 41451520 than 41451520 itself. So it correctly gets rounded down to 41451519.999999992549....
When you convert 41451519.999999992549... to an integer it floors the number, resulting in one less than what you expect.
Floating point math is full of surprises. You should read What Every Computer Scientist Should Know About Floating-Point Arithmetic, but perhaps it's still too advanced for now. But it's important to be aware that yes, floating point is full of surprises, but no it isn't magic, and you can learn the pitfalls.
I have a program here that is supposed to sum up the series
1+1/2+1/3+1/4... etc
The only user entry is to enter how many times you want this sum to run for.
However, I keep getting the sum one.
#include <stdio.h>
int main(void)
{
int b,x; /* b is number of times program runs and x is the count*/
float sum;
printf("Enter the number of times you want series to run.\n");
scanf("%d", &b);
printf("x sum\n");
for(x=1,sum=0;x<b+1;x++)
{
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
}
return 0;
}
I don't quite get why it isn't working. As you can see, I did tell it to print x and when it did, x was incrementing correctly.The sum just kept adding up to one.
You have misplaced parentheses so you're doing integer division for 1/x and getting 0 for any value of x > 1.
I suggest you change:
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
to:
printf("%d %9.3f\n",x, (sum += 1.0f/x));
Two problems: one dull, one interesting.
1) 1 / x will be imprecise since 1 and x are both integral types and so the computation will be done in integer arithmetic. All the cast does is convert the resultant integral type to floating point. To resolve this, write 1.0 / x. Then 'x' is promoted to floating point prior to the division.
2) You should reverse the order of the for loop:
sum = 0.0;
for(x = b; x >= 1; --x)
(I've also moved the initialisation or sum from the for loop as sum = 0 is an expression of type float but x = b is an expression of type int so you ought not use the comma operator as they have different data types.)
The reason is subtle: you should only add floating points of similar magnitude. Doing the loop my way means the smaller values are added first.
The effect will be noticeable for high values of b; try it. Your original way will always understate the sum.
The problem is integer division when you do 1/x, which always result in 0 as long as x is greater than 1. Even it you later convert this to a float, the "damage" is already done. An easy fix would be to change the division to 1.0f/x.
Since you have declared x as an int, (1/x) returns 1 when x is 1 and 0 for x>1. So, sum remains 1. So you get the same result.
So, change (1/x) to 1.0f/x, so that the result is returned as a float
Here you are computing 1/x in which the fractional value is truncated. Converting it into float after the original value has been truncated doesn't make sense.
So change this to:-
printf("%d %9.3f\n",x, (sum +=(float)(1/x)));
to
printf("%d %9.3f\n",x, (sum += 1.0f/x));
The expression (1/x) will always be integer division. For the first run this will be 1/1 giving you 1. However, next time round it will be 1/2 which is 0. Basically for 1/x where x>1 the answer will be zero.
To get around this write the expression as 1.0/x which will cause x to be promoted to a double, giving you double division.