October 8th, 2013, 06:08 AM

C types problem :(
1.4000*10=14 but it gives 13
int sum=0;
float float_sum=0.0;
float_sum=1.4000;
sum=float_sum*10;
printf(" Sum : %d\n\n",sum);
I can't understand why? Please help me guys :(
October 8th, 2013, 10:20 AM

Obviously 1.4 could not be represented exactly as a binary fraction value, so it becomes 1.399999.... (print it full to see)
When you multiply by 10 you get 13.99999  and then casting to int simply cuts fraction, so you are left with your 13.
Use "round" function to round results before casting to int, for example.
This exercise could be of help too:
Rounding at CodeAbbey
October 8th, 2013, 10:21 AM

Also print out sum in floatingpoint format. You should find that it's something like 13.99999. When you convert a float to an integer, you truncate it, which means that you chop off the fractional part and keep the integer part. So 13.99999 truncates to 13.
BTW, sum could just as easily have been 14.000001, which would have truncated to 14. Read up on IEEE 754, which is the floatingpoint format being used. It's a form of "scientific notation", in which you have a fraction called the mantissa and an exponent that you use to move the binary point, just as you do in decimal. Yes, I did say "binary point", because that mantissa is in binary (base 2) instead of decimal (base 10) and you multiply it by two raised to the exponent. You can express exactly a value which is a power of two (eg, 1, 2, 4, 8, 16, 32, 64, etc), but all other numbers you can only approximate. You can get very very close to that value, but not exactly. It is therefore a logic error to expect a floatingpoint operation to yield an exact value.
When you investigate the floatingpoint format, these utilities I wrote may help you to see what various values look like. They both depend on being run on a littleendian machine, such as an Intel.
f2hex.c: converts a float value to hex
Code:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
float f;
if (argc != 2)
{
fprintf(stderr,"Usage: f2hex <floatingpoint value>");
exit(1);
}
f = (float)atof(argv[1]);
printf("%g = ",f);
for (i=3; i>= 0; i)
printf(" %02X",((unsigned char*)(&f))[i]);
printf("\n");
return 0;
}
d2hex.c: converts a double value to hex
Code:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
double f;
if (argc != 2)
{
fprintf(stderr,"Usage: d2hex <doubleingpoint value>");
exit(1);
}
f = atof(argv[1]);
printf("%g = ",f);
for (i=7; i>= 0; i)
printf(" %02X",((unsigned char*)(&f))[i]);
printf("\n");
return 0;
}
October 8th, 2013, 10:28 AM

Originally Posted by bashburak
1.4000*10=14 but it gives 13
int sum=0;
float float_sum=0.0;
float_sum=1.4000;
sum=float_sum*10;
printf(" Sum : %d\n\n",sum);
I can't understand why? Please help me guys :(
The problem is that sum is of type integer and you are trying to stuff a float into it. The float, float_sum, gets a part of it indiscriminately chopped off to fit into sum, which is smaller than a float, and causes a loss of data and hence the error.
Change sum to type float and that will fix it. Didn't your compiler issue a warning of possible loss of data for this line: sum=float_sum*10;?
And in case you didn't know, literals like 1.4000 or 10 also have a type. Any number that doesn't have a decimal point is an integer. And any number that has a decimal point is automatically a double, unless a "f" is used to denote a float type.
For example:
10 = integer.
1.40 = double.
1.40f = float.
In the line above, float_sum=1.4000;, you should be getting some kind of warning, like "truncation from 'double' to 'float' ". The compiler will give you a warning when it starts chopping things up so that you can check to see if there is any loss of data involved. It is good practice to compile so that there are no warnings in the first place.
Change this line: float_sum=1.4000; to this: float: sum=1.4000f; to eliminate the compiler's warning.
October 8th, 2013, 11:43 AM

I got it now :)
MandrewP, i am using similar code in a function which should return int type, so changing int sum to float is not solving my problem. thanks anyway for consideration :)
rodiongork, ı followed what u said and printed to see variations.
you are right, 14.0 is something like 13.999....
so here it is with examples :
code :

/*first of all if we assign to a int variable something like f_x*10 that which has reel value result, it looses data. */
int i_x;
float f_x;
f_x=1.4;
i_x=f_x*10; prints
printf("\n\nfloat x : %.17f \n",f_x); // 13.9999997615......
printf("\n\n int x : %d \n",i_x); // prints 13
/*if we assign to a reel variable f_a*10 = 13.9999997615......
new f_a will be 14.000000... */
int i_a;
float f_a;
f_a=1.4*10;
printf("\n\nfloat a : %.17f \n",f_a); //prints 14.00000...
i_a=f_a;
printf("\n\n int a : %d \n",i_a); // prints 14
//similar here
int i_b;
float f_b;
f_b=1.4;
f_b=f_b*10;
printf("\n\nfloat b : %.17f \n",f_b);
i_b=f_b;
printf("\n\n int b : %d \n",i_b);

after all, i understood that, when we wont to assign reel value(like 14.0) to a int variable, first we will assign it to a reel
variable and then we will assign reel variable to a int variable.
assigning "reel result" directly to a int variable may cause data loses.
am I right ? :)
sorry for weak English :p
October 8th, 2013, 03:54 PM

Originally Posted by bashburak
MandrewP, i am using similar code in a function which should return int type, so changing int sum to float is not solving my problem.
To force a conversion to integer to round to the nearest integer, add 0.5 to the floatingpoint value prior to the integer cast:
Code:
float float_sum = 1.4f ;
int sum = (int)((float_sum * 10.0f) + 0.5f) ;
printf( "Sum : %d\n", sum ) ;
Try that with float_sum = 1.34, 1.35, 1.39, 1.44, and 1.45 for example to see how it works.
Last edited by clifford; October 8th, 2013 at 04:01 PM.
October 8th, 2013, 04:05 PM

Originally Posted by bashburak
printf("\n\nfloat x : %.17f \n",f_x); // 13.9999997615......
The single precision "float" type is only good for 6 decimal significant figures, so a precision of .17 is rather too much. "double" is only good for 15 even.
October 8th, 2013, 04:42 PM

To force a conversion to integer to round to the nearest integer, add 0.5 to the floatingpoint value prior to the integer cast:
I also used your method clifford in :
int sum_of_digit_values2(int);
int sum_of_digit_values3(int);
functions, it works, thanks :)
Code:
int sum_of_digit_values1(int);
int sum_of_digit_values2(int);
int sum_of_digit_values3(int);
int main()
{
int number;
printf("\n Enter a number : ");
scanf("%d",&number);
printf("\n\n 1.Sum of values of digits : %d\n\n",sum_of_digit_values1(number));
printf("\n\n 2.Sum of values of digits : %d\n\n",sum_of_digit_values2(number));
printf("\n\n 3.Sum of values of digits : %d\n\n",sum_of_digit_values3(number));
}
int sum_of_digit_values1(int x)
{
int decimal,sum=0;
do
{
decimal = (int)(10.0f*((float)(x/10.0f)x/10)+0.5f);
printf("\n\tDecimal part : %d \n",decimal);
x=x/10;
sum+=decimal;
}
while(x>=1);
return(sum);
}
int sum_of_digit_values2(int x)
{
int sum=0;
do
{
sum+=x%10;
x=x/10;
}
while(x>0);
return(sum);
}
int sum_of_digit_values3(int x)
{
int sum=0;
do
{
sum+=(int)(10.0f*((float)(x/10.0f)x/10)+0.5f);
x=x/10;
}
while(x>=1);
return(sum);
}
October 9th, 2013, 04:57 AM

Note that in teh following expression (ant other similar constructs in your code):
Originally Posted by bashburak
Code:
decimal = (int)(10.0f*((float)(x/10.0f)x/10)+0.5f);
the subexpression x/10.0f already has type float because the 10.0f forces an implicit cast before your explicit cast. If you want to avoid the implicit cast then the expression should be:
Code:
decimal = (int)(10.0f * (((float)x / 10.0f)  x / 10) + 0.5f) ;
in either cast you get the same result and it may even be clearer to remove the explicit cast since teh intent is clear by the use of 10.0f:
Code:
decimal = (int)(10.0f * ((x / 10.0f)  x / 10) + 0.5f) ;
October 9th, 2013, 06:22 AM

function pow() has real type, so if i assign it to a int variable, will it cause data lose?
example :
int delta;
delta=pow(b,2)4*a*c;
or should i convert it to int like written below?
int delta;
delta=(int)pow(b,2)4*a*c;
October 9th, 2013, 04:22 PM

Originally Posted by bashburak
or should i convert it to int like written below?
In terms of the result, there is no difference between an implicit or an explicit cast, an explicit cast however is a clear indication that you intended to assign an integer and that it is not a programming error. This will help anyone who later maintains your code (including yourself). It may also silence compiler or static analysis warnings.