Trying to print answer to equation and getting zero in C. - c

printf("Percent decrease: ");
printf("%.2f", (float)((orgChar-codeChar)/orgChar));
I'm using this statement to print some results to my command console, however, I end up with zero. Putting the equation into another variable doesn't work either.
orgChar = 91 and codeChar = 13, how do I print out this equation?

Integer division will lead to result 0 here and you are type casting the result later to float so eventually you will end up with 0
Make any one of the variables float before division
(orgChar-codeChar)/(float)orgChar

As others have mentioned, the subtraction and division are done using integer math before the cast to (float). By that point, the integer division has a truncated result of 0. Instead:
// (float)((orgChar-codeChar)/orgChar)
((float) orgChar - codeChar)/orgChar
// or
(orgChar - codeChar)/ (float) orgChar
As the float argument gets converted to double as part of the "usual argument promotion" of arguments to a variadic function like printf(), might as well do
printf("%.2f", (orgChar-codeChar)/ (double) orgChar);
Casting, in general, should be avoided. Some casts unintentionally narrow the operation. If unsigned is 32-bit and a1 is uint64_t, then a1 was narrowed before the shift and unexpected results may occur. If a1 was a char, it is nicely converted without trouble to an unsigned.
The second method of *1u will not narrow. It will insure a2*1u is at least the width of an unsigned.
unsigned sh1 = (unsigned) a1 >> b1; // avoid
unsigned sh2 = a2*1u >> b2; // better
So recommend, rather than (float) or (double), use the idiom of multiplying by 1.
printf("%.2f", (orgChar - codeChar) * 1.0 / orgChar);

you don't need to typecast the whole expression. you can simply type cast either the numerator or the denominator to get the float result with precision of 2 decimal places.
for eg:
here in this code defining a variable c as float doesnt guarantee the result to be float.for getting the precise result you need to typecast either the numerator or denominator.

You shouldn't need to cast to float at all. Simply make sure both variables are of type float or double before attempting to print them as floats. This means either declaring the variables as floats, or using the correct function, such as atof () when converting the data to floats (normally this is done when you get the data from the command-line or a file.)
This should work...
#include <stdio.h>
int
main (void)
{
float orgChar = 91;
float codeChar = 13;
printf ("%.2f\n", (orgChar - codeChar) / orgChar);
return 0;
}

Related

Is it defined what will happen if you shift a float?

I am following This video tutorial to implement a raycaster. It contains this code:
if(ra > PI) { ry = (((int)py>>6)<<6)-0.0001; rx=(py-ry)*aTan+px; yo=-64; xo=-yo*aTan; }//looking up
I hope I have transcribed this correctly. In particular, my question is about casting py (it's declared as float) to integer, shifting it back and forth, subtracting something, and then assigning it to a ry (also a float) This line of code is entered at time 7:24, where he also explains that he wants to
round the y position to the nearest 64th value
(I'm unsure if that means the nearest multiple of 64 or the nearest (1/64), but I know that the 6 in the source is derived from the number 64, being 2⁶)
For one thing, I think that it would be valid for the compiler to load (say) a 32-bit float into a machine register, and then shift that value down by six spaces, and then shift it back up by six spaces (these two operations could interfere with the mantissa, or the exponent, or maybe something else, or these two operations could be deleted by a peephole optimisation step.)
Also I think it would be valid for the compiler to make demons fly out of your nose when this statement is executed.
So my question is, is (((int)py>>6)<<6) defined in C when py is float?
is (((int)py>>6)<<6) defined in C when py is float?
It is certainly undefined behavior (UB) for many float. The cast to an int is UB for float with a whole number value outside the [INT_MIN ... INT_MAX] range.
So code is UB for about 38% of all typical float - the large valued ones, NaNs and infinities.
For typical float, a cast to int128_t is defined for nearly all float.
To get to OP's goal, code could use the below, which I believe to be well defined for all float.
If anything, use the below to assess the correctness of one's crafted code.
// round the y position to the nearest 64th value
float round_to_64th(float x) {
if (isfinite(x)) {
float ipart;
// The modf functions break the argument value into integral and fractional parts
float frac = modff(x, &ipart);
x = ipart + roundf(frac*64)/64;
}
return x;
}
"I'm unsure if that means the nearest multiple of 64 or the nearest (1/64)"
On review, OP's code is attempting to truncate to the nearest multiple of 64 or 2⁶.
It is still UB for many float.
That code doesn't shift a float because the bitshift operators aren't defined for floating-point types. If you try it you will get a compiler error.
Notice that the code is (int)py >> 6, the float is cast to an int before the shift operation. The integer value is what is being shifted.
If your question is "what will happen if you shift a float?", the answer is it won't compile. Example on Compiler Explorer.
The best possible recreation of the shift ops for floating points, in short, without using additional functions are the following:
Left shift:
ShiftFloat(py,6,1);
Right shift:
ShiftFloat(py,6,0);
float ShiftFloat(float x, int count, int ismultiplication)
{
float value = x;
for (int i = 0; i < count; ++i)
{
value *= (powf(0.5,(float)(ismultiplication^1)) / powf(2.0,(float)(ismultiplication)));
}
return count != 0 ? value : x;
}

C don't get the right result

I need the result of this variable in a program, but I don't understand why I can't get the right result.
double r = pow((3/2), 2) * 0.0001;
printf("%f", r);
The problem is integer division, where the fractional part (remainder) is discarded
Try:
double r = pow((3.0/2.0), 2) * 0.0001;
The first argument of the pow() expects a double. Because the ratio: 3/2 uses integer values, the result passed to the argument is 1. By changing to float values, the result of the division can retain the fractional part, and the result becomes 1.5, the form expected by the function.
(3/2) involves two integers, so it's integer division, with the result 1. What you want is floating point (double) division, so coerce the division to use doubles by writing it as (3.0/2.0)

Why do we separately cast to "float" in an integer division?

For example:
int number1 = 1, number2= 2;
float variable = (float)number1/(float)number2;
Instead of this, Why can't we use "float" only once? For example:
int number1 = 1, number2= 2;
float variable = (float)(number1/number2);
The objective is to avoid the truncation that comes with integer division. This requires that at least one of the operands of the division be a floating point number. Thus you only need one cast to float, but in the right place. For example,
float variable = number1/(float)number2; // denominator is float
or
float variable = ((float)number1)/number2; // numerator is float
Note that in the second example, one extra set of parentheses has been added for clarity, but due to precedence rules, it is the same as
float variable = (float)number1/number2; // numerator is float, same as above
Also note that in your second example,
float variable = (float)(number1/number2);
the cast to float is applied after the integer division, so this does not avoid truncation. Since the result of the expression is assigned to a float anyway, it is the exact of
float variable = number1/number2;
You can write either expression, but you get different results.
With float variable = (float)(number1 / number2); the value in variable is 0, because the division is done as integer division, and 1/2 is 0, and the result is converted.
With float variable = (float)number1 / (float)number2;, the value in variable is 0.5, because the division is done as floating point division.
Either one of the casts in float variable = (float)number1 / (float)number2; can be omitted and the result is the same; the other operand is converted from int to float before the division occurs.
Since number1 and number2 are ints, the division performed will be integral division. Thus, number1/number2 will evaluate to the int 0. To do floating point arithmetic instead, you need to cast them. Note that simply casting one will suffice, since the other one will be implicitly promoted. So, you can just say ((float)number1)/number2.
In the First case,
1/2 results 0
In the second case, you can use float once, but it has to be applied with one of the numbers before division
1.0/2.0 or 1.0/2 or 1/2.0 results 0.5

Floating point rounding in C

I've run into some weird rounding behaviour with floats. The code below demonstrates the problem. What is the best way to solve this? I've been looking for solutions but haven't had much luck.
#include<stdio.h>
int main(void)
{
float t;
t = 5592411;
printf("%f\n", 1.5*t);
t *= 1.5;
printf("%f\n", t);
return 0;
}
The code above should print out the same value, but I get this on my setup using GCC 4.7.2:
8388616.500000
8388616.000000
If I use a calculator, I get the first value, so I assume the second is being rounded somehow. I have identical Fortran code which does not round the value(has the 0.5).
1.5 is a double constant rather than a float and C has automatic promotion rules. So when you perform 1.5*t what happens is (i) t is converted to a double; (ii) that double is multiplied by the double 1.5; and (iii) the double is printed (as %f is the formatter for a double).
Conversely, t *= 1.5 promotes t to a double, performs a double multiplication and then truncates the result to store it back into a [single precision] float.
For evidence, try either:
float t;
t = 5592411;
printf("%f\n", 1.5f*t); // multiply a float by a float, for no promotion
t *= 1.5;
printf("%f\n", t);
return 0;
Or:
double t; // store our intermediate results in a double
t = 5592411;
printf("%f\n", 1.5f*t);
t *= 1.5;
printf("%f\n", t);
return 0;
The first calculation is done with double precision, the second is calculated the same, but truncated to single precision in the assignment to float.
If you use double for your variable, you'll get the same result. It's a good idea to use this type over float whenever accuracy may be a concern.
In the first case, the result is a double which can precisely represent the desired value.
In the second case, the result is a float which can't precisely represent the desired value.
Try the same with double and you'll end up with the same results either way.
#include<stdio.h>
int main(void)
{
double t;
t = 5592411;
printf("%f\n", 1.5*t);
t *= 1.5;
printf("%f\n", t);
return 0;
}
Writing 1.5 in C code is interpreted as a double, which has more precision than the float type.
The first case,
printf("%f\n", 1.5*t);
results in t being implicitly converted to a double (with greater precision) and then multiplied. The printf function, which casts the input corresponding to %f anyway, prints the result, which is also a double.
The second case has the 1.5 being converted to the float type, which has less precision and cannot store as small details.
If you want to avoid this effect, use 1.5f instead on 1.5 to use floats, or change the type of t to double.
Whether this would work at all depends on the machine representation of floats and doubles. Passing a float on a typical 32 bit architecture pushes 4 bytes on the argument stack. Passing a double would push 8 bytes. Passing a double but using %f is asking to treat it as a float which will look at the first 4 bytes pushed in our typical case. Depending on machine representation this might be close to the intended result or might be way out in left field.

how to truncate a number with a decimal point into a int? what's the function for this?

The problem occurs when I do a division operation. I would like to know who to truncate a number with a decimal point into a whole number such as 2, 4, 67.
It truncates automatically is you assign value to "int" variable:
int c;
c = a/b;
Or you can cast like this:
c = (int) (a/b);
This truncates it even if c is defined as float or double.
Usually truncation is not the best (depends what you want to achieve of course). Usually result is rounded like this:
c= round(a/b,0);
is more intelligent because rounds result properly. If you use linux, you can easily get reference with "man round" about exact data types etc.
You can use the trunc() function defined in math.h. It will remove fractional part and will return nearest integer not larger than the given number.
This is how it is defined:
double trunc(double x);
Below is how you can use it:
double a = 18.67;
double b = 3.8;
int c = trunc(a/b);
You can check man trunc on Linux to get more details about this function. As pointed out in previous answers, you can cast division result to integer or it will automatically be truncated if assigned to integer but if you were interested to know about a C function which does the job then trunc() is the one.
int result = (int)ceilf(myFloat );
int result = (int)roundf(myFloat );
int result = (int)floor(myFloat);
float result = ceilf(myFloat );
float result = roundf(myFloat );
float result = floor(myFloat);
I think it will be helpful to you.
Manually or implicitly casting from a floating-point type to an integral type causes automatic truncation toward zero. Keep in mind that if the integral type is not sufficiently large to store the value, overflow will occur. If you simply need to print the value with everything past the decimal point truncated, use printf():
printf("%.0f", floor(float_val));
As Tõnu Samuel has pointed out, that printf() invocation will actually round the floating-point parameter by default.

Resources