correct C casts - c

I'm not so sure about correct casts, here especially from unsigned int and #defines (whatever type that is) to double.
In this example
#define SPEEDSENSOR_EDGES_NUM 10
int speed_counter_left;
double result = speed_counter_left / SPEEDSENSOR_EDGES_NUM;
the result always is 0 when speed_counter_left is < 10.
So I put in some casts:
double result = (double) ((double) speed_counter_left / (double) SPEEDSENSOR_EDGES_NUM);
This is correct, but I think there are too many casts. How can I figure out the correct way with least casts?

Having one double operand should be enough:
double result = (double)speed_counter_left / SPEEDSENSOR_EDGES_NUM;
The cast "sticks" closest to speed_counter_left. So it's essentially equivalent to:
double result = ((double)speed_counter_left) / SPEEDSENSOR_EDGES_NUM;
and #defines (whatever type that is) to double.
The standard says:
6.4.4.1 - 5
The type of an integer constant is the first of the corresponding list
in which its value can be represented.
And (for decimal constants without suffixes) the list goes: int, long int, long long int.

No need to cast, make SPEEDSENSOR_EDGES_NUM a double by using 10.0 instead of 10.
#define SPEEDSENSOR_EDGES_NUM 10.0
int speed_counter_left;
double result = speed_counter_left / SPEEDSENSOR_EDGES_NUM;

Related

Can a int value added to a float value?

/**Program for internal typecasting of the compiler**/
#include<stdio.h>
int main(void)
{
float b = 0;
// The Second operand is a integer value which gets added to first operand
// which is of float type. Will the second operand be typecasted to float?
b = (float)15/2 + 15/2;
printf("b is %f\n",b);
return 0;
}
OUTPUT : b is 14.500000
Yes, an integral value can be added to a float value.
The basic math operations (+, -, *, /), when given an operand of type float and int, the int is converted to float first.
So 15.0f + 2 will convert 2 to float (i.e. to 2.0f) and the result is 17.0f.
In your expression (float)15/2 + 15/2, since / has higher precedence than +, the effect will the same as computing ((float)15/2) + (15/2).
(float)15/2 explicitly converts 15 to float and therefore implicitly converts 2 to float, yielding the final result of division as 7.5f.
However, 15/2 does an integer division, so produces the result 7 (there is no implicit conversion to float here).
Since (float)15/2 has been computed as a float, the value 7 is then converted to float before addition. The result will therefore be 14.5f.
Note: floating point types are also characterised by finite precision and rounding error that affects operations. I've ignored that in the above (and it is unlikely to have a notable effect with the particular example anyway).
Note 2: Old versions of C (before the C89/90 standard) actually converted float operands to double in expressions (and therefore had to convert values of type double back to float, when storing the result in a variable of type float). Thankfully the C89/90 standard fixed that.
Rule of thumb: When doing an arithmetic calculation between two different built-in types, the "smaller" type will be converted into the "larger" type.
double > float > long long(C99) > long > short > char.
b = (float)15/2 + 15/2;
Here the first part, (float)15/2 is equivalent to 15.0f / 2. Because an operation involving a "larger" type and a "smaller" type will yield a result in the "larger" type, (float)15/2 is 7.500000, or 7.5f.
When it comes to 15/2, since both operands are integers, the operation is done only on integer level. Therefore the decimal point is stripped (from int), and only gives 7 as a result.
So the expression is calculated into
b = 7.5f + 7;
No doubt you'll have 14.500000 as the final result, because it's exactly 14.5f.
b = (float)15/2 + 15/2;
The first one((float)15/2) will work fine. The second one will also work but will be converted into an integer first, so you will lose precision. Like:
b = (float)15/2 + 15/2;
b = 7.500000f + 7
b = 14.500000
It's worth asking: if an integer value could not be added to floating-point value, what would the symptom be?
Compiler issues error or warning message.
Something gets truncated; you don't get the result you want.
Undefined behavior: you might or might not get the result you want, and the compiler might or might not warn you about it.
But in fact none of these things happen. When you add an integer to a floating-point value, the compiler automatically converts the integer to a floating-point value so it can do the addition that way, and this is perfectly well defined. For example, if you have the code
double d = 7.5;
int i = 7;
double result = d + i;
the compiler interprets this just as if you had written
double result = d + (double)i;
And it works this way for just about all operations: the same logic is applied when you subtract, multiply, or divide a floating-point value and an integer.
And it works this way for just about all types. If you add a long int and an int, the plain int automatically gets converted to a long.
As a general rule (and I really can't think of too many exceptions), the compiler always wants to do arithmetic on two values of the same type. So whenever you have two values of different type, the compiler will just about always convert one of them for you. The full set of rules for how it does this are rather elaborate, but they're all supposed to make sense, and do what you want. The full set of rules is called the usual arithmetic conversions, and if you do a Google search on that phrase you'll find lots of explanations.
One case that does not necessarily do what you want is when the two variables are not different types. In particular, if the two variables are both integers, and the operation you're doing is division, the compiler doesn't have to convert anything: it divides the integer by the integer, discarding any remainder, and gives you an integer result. So if you have
int i = 1;
int j = 2;
int k = i / j;
then k ends up containing 0. And if you have
double d = i / j;
then d ends up containing 0 also, because the compiler follows exactly the same rules when performing the division; it doesn't "peek outside" to see that it's going to need a floating-point result.
P.S. I said, "As a general rule, the compiler always wants to do arithmetic on two values of the same type", and I said I couldn't think of too many exceptions. But if you're curious, two exceptions are the << and >> operators. If you have x << y, where x is a long int and y is a plain int, the compiler does not have to convert y to a long int first.

Trying to print answer to equation and getting zero in 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;
}

Correct datatype for a variable

I have a question like this:
Which of the following is the correct datatype for the variable like this:
a = 23.5
a) float
b) double
c) long double
d) None
According to me, it should be double. Because, if we
float a = 23.5
Then, actually, we are initializing a float variable by a double constant. Am I right saying that it is option b?
It depends on what type you need for a to be in your program logic, not what type of value it's initialized.
Yes, float a = 23.5;, there is a conversion from the double literal 23.5 to the float variable a, but it's fine. For instance, to initialize a double variable to 42.0, people usually use
double a = 42;
in which 42 is of type int, instead of the longer
double a = 42.0;
So in my opinion, float, double, or long double can all be considered correct here.
You can declare this variable as double, float, or long double.
The difference is in the range of the type.
For example (one possible way):
float- 4 bytes
double - 8 bytes
long double - 12 bytes
You can see more details here: http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/CONCEPT/data_types.html
"It depends on" is the right answer.
There are more options then the three you mention.
If yo can safely assume that your numbers are either an integer, or
an integer +1/2 then storing 2 * i in an integral type may be the
right choice.
Another option is a rational number. There are
libraries out there for this.

casting integer division into double in C

Why does the code
double slope = (double)changeY/changeZ
set slope to 0.0, when in the program I have, changeX = 20 and changeY = 10 (both ints)?
It sounds like you are using the wrong variable. Try this:
int changeX = 20;
int changeY = 10;
double slope = (double)changeY/changeX;
The cast operator () has higher priority than /. This expression will get evaluated as:
Cast changeY to a double.
Implicitly convert changeX to a double. If one operand is double, then the other operand gets balanced to a double as well (this is formally called "the usual arithmetic conversions").
Divide the two operands. The result will be a double.
Store this temporary "result-double" into another double called slope.

How to use % operator for float values in c

When I use % operator on float values I get error stating that "invalid operands to binary % (have ‘float’ and ‘double’)".I want to enter the integers value only but the numbers are very large(not in the range of int type)so to avoid the inconvenience I use float.Is there any way to use % operator on such large integer values????
You can use the fmod function from the standard math library. Its prototype is in the standard header <math.h>.
You're probably better off using long long, which has greater precision than double in most systems.
Note: If your numbers are bigger than a long long can hold, then fmod probably won't behave the way you want it to. In that case, your best bet is a bigint library, such as this one.
The % operator is only defined for integer type operands; you'll need to use the fmod* library functions for floating-point types:
#include <math.h>
double fmod(double x, double y);
float fmodf(float x, float y);
long double fmodl(long double x, long double y);
When I haven't had easy access to fmod or other libraries (for example, doing a quick Arduino sketch), I find that the following works well enough:
float someValue = 0.0;
// later...
// Since someValue = (someValue + 1) % 256 won't work for floats...
someValue += 1.0; // (or whatever increment you want to use)
while (someValue >= 256.0){
someValue -= 256.0;
}
consider : int 32 bit and long long int of 64 bits
Yes, %(modulo) operator isn't work with floats and double.. if you want to do the modulo operation on large number you can check long long int(64bits) might this help you.
still the range grater than 64 bits then in that case you need to store the data in .. string and do the modulo operation algorithmically.
or either you can go to any scripting language like python
If you want to use an int use long long, don't use a format that is non-ideal for your problem if a better format exists.

Resources