I am asking a user for two non-negative integer values in C. I then want to convert these to percentages (expressed as decimals). Unfortunately, my floats are coming up as zeroes. Why is this, and how do I fix it?
int a = 5;
int b = 10;
int total = a + b;
float a_percent = a / total;
float b_percent = b / total;
printf("%.2f, %.2f\n", a_percent, b_percent);
You aren't using floats, you're using integers, and so the integral division gives zero (which is then assigned to a float).
To perform a floating-point operation, you must first convert the integers (or at least one of them) to a float. Conveniently, we just use total:
float total = a + b; // exact
float ap = a / total;
float bp = b / total; // OK, these are now floating-point operations
In addition to the problems others have pointed out, the ratio won't be a percentage until you multiply it by 100.0.
An int divided by an int will always return an int. You'll have to make one of the two arguments a float before dividing:
float a_percent = (float) a / total;
float b_percent = (float) b / total;
I am not a C expert, but my guess is because dividing an int by an int always results in an int.
You may need to do something like this:
float a_percent = (float)a/total;
float b_percent = (float)b/total;
You're first performing an integer division, then converting the result to floating point. This will not give the results you want. Either make total a floating point value to begin with (so that the types get automatically promoted right) or cast a and b to (float) before performing the division.
You are using integer math not floating point here.
Try:
float a_percent = a/(float)total;
float b_percent = b/(float)total;
For a simple percentage you may be happier using fixed-point. Just multiply your numerator (a or b) by 100 and you'll get the percentage from the division. forex:
int a = 5;
int b = 10;
int total = a + b;
int a_percent = 100*a/total;
int b_percent = 100*b/total;
printf("a%%=%d, b%%=d\n", a_percent, b_percent);
Related
I need to apply a formula to three variables. Some of the operations (divisions) give me a 0 instead of the proper number. So I get a different result from what I expected from the formula.
I think that the problem is related to the way C manages data types and their remainders. For this reason, I tried to transform int variables into float variables or to round the numbers that I divided. But all of this is still not working and I'm not able to understand what I'm missing.
Could you please have a look at my code and let me know where is the mistake?
Thanks
double grade(int lc, int wc, int sc)
{
wc = (float)wc;
lc = (float)lc;
sc = (float)sc;
float L = round((wc/100)/lc);
float S = round((wc/100)/sc);
float index = 0.0588 * L - 0.296 * S - 15.8;
return index;
}
Problem:
wc = (float)wc;
lc = (float)lc;
sc = (float)sc;
All these statements do not do what you think because the types of these variables are originally int.
You are converting an int to float and assigning it back to int.
Solution:
Pass the values to a float rather than int to the function, implicit conversion will take care of the rest.
Change your function signature to
double grade(float lc, float wc, float sc)
Or just do this (the other operands will not need the cast to float since it enough if only one of the operands is it, then the others will be converted to it implicitly)
double grade(int lc, int wc, int sc)
{
float L = round(((float)wc/100)/lc);
float S = round(((float)wc/100)/sc);
float index = 0.0588 * L - 0.296 * S - 15.8;
return index;
}
Note that the return type is double, but you use just floats. Use double instead of floats in the function as types as well OR change return type to float.
The mistake is that this wc = (float)wc; is essentially this wc = (int)(float)wc; since wc type is int. Basically nothing happens, therefore when you make your calculation like wc/100, then this will be an integer division resulting in integer, so if wc is less than 100 (and >= 0), then the result is 0 and not a real number as you would expect.
wc = (float)wc; casts an int to a float, converts back to int, then assigns. No real benefit here.
wc/100 is integer division, which discards the fraction of the quotient. Not likely what OP wants.
Converting int to float risks losing precision as so a less precise answer. double is better for wide ranging int values.
Code mixes uses of float and double with a call to a double round(double), double multiplication and conversions from float to double to float to double. Simplify and use double throughout.
double grade(int lc, int wc, int sc) {
// v------v `double` division
double L = round(wc/100.0/lc);
double S = round(wc/100.0/sc);
return 0.0588 * L - 0.296 * S - 15.8;
}
Example (in C):
#include<stdio.h>
int main()
{
int a, b = 999;
float c = 0.0;
scanf("%d", &a);
c = (float)a/b;
printf("%.3lf...", c);
return 0;
}
If I put 998 it will come out 0.999, but I want the result be 0.998; how?
It looks like you want to truncate instead of round.
The mathematical result of 999/998 is 0.9989989989... Rounded to three decimal places, that is 0.999. So if you use %.3f to print it, that's what you're going to get.
When you convert a floating-point number to integer in C, the fractional part is truncated. So if you had the number 998.9989989 and you converted it to an int, you'd get 998. So you can get the result you want by multiplying by 1000, truncating to an int, and dividing by 1000 again:
c = c * 1000;
c = (int)c;
c = c / 1000;
Or you could shorten that to
c = (int)(c * 1000) / 1000.;
This will work fine for problems such as 998/999 ≈ 0.998, but you're close to the edge of where type float's limited precision will start introducing its own rounding issues. Using double would be a better choice. (Type float's limited precision almost always introduces issues.)
I need to perform a simple multiplication of 400 * 256.3. The result is 102520. Straight forward and simple. But to implement this multiplication in C++ (or C) is a little tricky and confusing to me.
I understand floating point number is not represented as it is in computer. I wrote the code to illustrate the situation. Output is attached too.
So, if I do the multiplication using float type variable, I am subjected to rounding error. Using double type variable would have avoided the problem. But let's say I have a very limited resource on the embedded system and I have to optimize the variable type to the very best I could, how can I perform the multiplication using float type variable and not susceptible to rounding error?
I knew the floating point math done by computer is not broken at all. But I am curious for best practice to perform floating point math. 256.3 is just a value for illustration. I would not know what floating point value I will get during runtime. But it is for sure, a floating point value.
int main()
{
//perform 400 * 256.3
//result should be 102520
float floatResult = 0.00f;
int intResult = 0;
double doubleResult = 0.00;
//float = int * float
floatResult = 400 * 256.3f;
printf("400 * 256.3f = (float)->%f\n", floatResult);
//float = float * float
floatResult = 400.00f * 256.3f;
printf("400.00f * 256.3f = (float)->%f\n", floatResult);
printf("\n");
//int = int * float
intResult = 400 * 256.3f;
printf("400 * 256.3f = (int)->%d\n", intResult);
//int = float * float;
intResult = 400.00f * 256.3f;
printf("400.00f * 256.3f = (int)->%d\n", intResult);
printf("\n");
//double = double * double
doubleResult = 400.00 * 256.3;
printf("400.00 * 256.3 = (double)->%f\n", doubleResult);
//int = double * double;
intResult = 400.00 * 256.3;
printf("400.00 * 256.3 = (int)->%d\n", intResult);
printf("\n");
//double = int * double
doubleResult = 400 * 256.3;
printf("400 * 256.3 = (double)->%f\n", doubleResult);
//int = int * double
intResult = 400 * 256.3;
printf("400 * 256.3 = (int)->%d\n", intResult);
printf("\n");
//will double give me rounding error?
if (((400.00 * 256.3) - 102520) != 0) {
printf("Double give me rounding error!\n");
}
//will float give me rounding error?
if (((400.00f * 256.3f) - 102520) != 0) {
printf("Float give me rounding error!\n");
}
return 0;
}
Output from the code above
If you have a fixed number of decimal digits (1 in the case of 256.3) as well as a bounded range of the results, you can use integer multiplication, and adjust for the shift in decimal digits through integer division:
int result = (400 * 2563) / 10;
Rounding errors are inherent to floating point arithmetics, except for a few cases where all operands can be represented exactly. Whether you choose float or double just influences when the error occurs, not if.
First of all, understand that type double has all the same problems as type float. Neither type has infinite precision, so both types are susceptible to precision loss and other problems.
As to what you can do: there are many different problems that come up, depending on what you're doing, and many techniques to overcome them. Many, many words have been written on these techniques; I suggest doing a web search on "avoiding floating point error". But the basic points are:
Know that floating-point results are never exact
Don't try to compare floating-point numbers for exact equality
When comparing floating-point numbers for equality, use an appropriate "epsilon" range
After calculation, it is often appropriate to explicitly round the final value to the desired precision (especially when printing it out)
Beware of algorithms which cause the precision loss to increase with each step
See also https://www.eskimo.com/~scs/cclass/handouts/sciprog.html .
A key weakness to displaying the problem is the conversion to int intResult. The posted problem is about multiplying and comparing, but code only shows issues surrounding int conversion.
If code needs to convert a FP value to the nearest whole number, uses rint(), round(), nearbyint() or lround(), not integer assignment.
I have two int values that I want to combine into a decimal number. So for example, I have A = 1234 and B = 323444. Both are int and I do not want to change it if possible.
I want to combine them to get 1234234233.323444.
My initial method was to divide b by 1e6 and add it to A to get my value.
I assigned
int A = 1234234233;
int B = 323444;
double C;
A = 1234;
B = 323444;
C = A + (B/ 1000000);
printf("%.6f\n", C);
I get 1234234233.000000 as a result. It rounds my C and I do not want that as I want 1234234233.323444
how can I solve this?
Try like this:
C = A + (B/ 1000000.0);
ie, make the denominator as double so that when integer by integer division is made it does not return weird results like you are getting.
NOTE:-
Integer/Integer = Integer
Integer/Double = Double
Double/Integer = Double
Double/Double = Double
B is an integer and dividing an integer by another integer (10000 here) will always give an integer and that's why you are getting unexpected result. Changing 10000, which is of type int, to 10000.0 (double type) will solve this problem. It seem that 10000 and 10000.0 are integer by mathematical definition but both are of different type in programming languages, former is of type int while latter is of type double.
C = A + (B/ 1000000.0);
or
C = A + ((double)B/ 1000000);
to get the expected result.
Is this even possible? i tried to google it but i cant seem to find the right answer.
I need to limit the decimal places since the answer will really differ if there is only 3 decimal places than 5, so i was hoping that you could help me with these. i know how to print with 3 decimal places but to declare a variable to only hold 3 decimal places is something i do not know. i could also use some links if you have any.
float sinfa(float num1)
{
float fc;
float powers;
float rad_angle;
rad_angle = num1 * (PI / 180.0);
powers = pow(num1,4);
fc = sin(rad_angle)-powers+1;
return (fc);
}
float sinfb(float num2)
{
float fd;
float powerss;
float rad_angle1;
rad_angle1 = num2 * (PI / 180.0);
powerss = pow(num2,4);
fd = sin(rad_angle1)-powerss+1;
return (fd);
}
float tp(float fa,float fb,float num1,float num2)
{
float p;
float fm2 = fa*num2;
float fm1 = fb*num1;
p = (fm2-fm1)/(fa-fb);
return (p);
}
float sinp(float p1)
{
float fop;
float ppowers;
float rad_angle2;
rad_angle2 = p1 * (PI / 180.0);
ppowers = pow(p1,4);
fop = sin(rad_angle2)-ppowers+1;
return (fop);
}
Thank you
Can't be done. A float is a 32-bit floating-point value in every C compiler I have ever used. There is nothing standard in the language to redefine how it works.
You could write a set of fixed-point functions that store values multiplied by 1000, or use a general library that implements fixed-point with arbitrary precision and set the precision to 3 decimal digits.
C++ fixed point library?
It can be done!
int intVal = 1.234567 * 1000; // result: 1234
float floatVal = (float)intVal / 1000; // result: 1.234
The trick is to:
Move the required number of digits to the left-hand side of the decimal place.
Truncate all the digits on the right-hand side of the decimal place.
Move the required number of digits back to the right-hand side of the decimal place.