Why is an int promoted in multiplication but not division? [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
It's my understanding that when multiplying, for example, a float and an int the int gets promoted to a float and so the product can have a fractional part. On the other hand, when dividing a float by an int there's no promotion and any fractional part of the quotient is discarded. What's the reason for this asymmetry?
float f1 = 13.3;
int i1 = 2;
float product = f1 * i1; // Product will be 26.6
float quotient = f1 / i1; // Quotient will be 6.0
Edit: Well, I guess I was just wrong. An int is promoted in division, too. Right? The truncation only applies to division with two ints. Right? What's the site best-practice here, should I just delete this question since it's so off base?

On the other hand, when dividing a float by an int there's no promotion and any fractional part of the quotient is discarded.
That is simply not correct. The fractional part is kept. The multiplication and division operations work in the same way in this sense.

If you run this program like:
#include <stdio.h>
int main()
{
float f1 = 13.3;
int i1 = 2;
float product = f1 * i1; // Product will be 26.6
float quotient = f1 / i1; // Quotient
printf( "product = %f\n",product );
printf( "quotient = %f\n", quotient );
}
then the output is
product = 26.600000
quotient = 6.650000
According to the C Standard (6.5.5 Multiplicative operators)
3 The usual arithmetic conversions are performed on the operands.
and (6.3.1.8 Usual arithmetic conversions)
Otherwise, if the corresponding real type of either operand is float,
the other operand is converted, without change of type domain, to a
type whose corresponding real type is float.62)

Related

How to print a double data type in C [duplicate]

This question already has answers here:
How to divide 2 int in c?
(5 answers)
C - double result returning the value of 0 [duplicate]
(2 answers)
Closed 4 years ago.
Why in C, when I print a double type variable with %f it shows 8.000000… but that is not the desire result . i want a result like 8.5000 how can i achieve this?
int main(){
int i, j;
double k;
i=8; j=9;
k = (i+j)/2;
printf("%f", k);
}
The problem is not with the format specifier, rather with the arithmatic operation.
By saying
k = (i+j)/2;
where, i and j and 2 - all are ints, you're doing integer division, and then, storing the result in a double. For integer division,
[..] When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded [...]
which is commonly known as "truncation towards zero". To avoid that from happenning, you need to enforce floating point arithmetic, by forcing or casting one of the operands to double (or float). Something like
k = ((double)i+j)/2;
or,
k = (i+j)/2.0; //2.0 is of type double
The point here is, if, in the operation, one of the operands is of the higher rank (double or float is higher ranked that int), all the operands will first be converted to the higher rank, and then the operation will be performed and the result will be of the type of the higher ranked type.
Since i and j are int the result is cast first to int. This looses precision. Explicitly cast to double k = (double)(i+j)/2
Comments are right. To better understand that: A C expression is evaluated in 'one chunk'. The right side of your assignment (i+j)/2 is a complete expression. Since it does only includes integer values, the arithmetic chosen will also be of integer type, (which leads to truncation of the result), creating temporary integer value (invisible to you), which is then assigned to a double.
You need to make at least one of the values in your expression a double (or float), then the compiler will promote all the arithmetic to floating point and the temporary value will also be of float type.
If you don't have a constant in your expression, you can also use casts:
((float)i+J)/2
It does not matter which of the 3 items get the cast, just one is enough.

C - explanation for this answer [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
int main(void)
{
float w = 8.456;
int b = 3;
printf("%d", (int)(b * w));
return 0;
}
Can't seem to understand how does this equal to 25, even though it's int * float and is displayed as an int, and what does int means in printf line... Isn't int multiply by float a 0?
b*w result is a float (=25.368) then you cast it to an int and it is truncated to 25.
NB:
If you were expecting the result to be 24, both variable should be ints.
See: c-language data type arithmetic rules
As you multiply an integer with a floating point number, the so called "usual arithmetic conversions" (UAC) will take place. According to the UAC, if one of the operands is a float and the other is an integer then both operand will be converted to float: 3.0 * 8.456 = 25.368. Later, in the printf when it is converted to an int then fractional part will be truncated that's why the result will be 25.

Is there a difference between these two operations? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I would like to ask if there is a difference in the result (s16Result) between
int16_t s16X, s16Y, s16Result;
s16Result = (int16_t) (s16X - s16Y);
and
int16_t s16X, s16Y, s16Result;
s16Result = (int16_t) ((uint16_t) s16X - (uint16_t) s16Y)
with s16X and s16Y having the datatype signed integer and therefore having the range -32767...32767 . Thank you.
These statements do not generally have the same behavior as defined by the C standard. Consider when s16X has the least value of its type (e.g., perhaps INT_MIN in an implementation where the int type is 16 bits, so it could be −32767) and s16Y is 2. Then, in:
s16Result = (T_S16) (s16X - s16Y)
the expression s16X - s16Y overflows—the mathematical result of −32769 is not representable in the int type, and the C standard does not define the result.
However, in:
s16Result = (T_S16) ((T_U16) s16X - (T_U16) s16Y)
the T_U16 type is presumably an unsigned 16-bit type. In this case, s16X is converted to the 16-bit type by adding or subtracting 65536, yielding 32769. s16Y retains its value of 2. Then the subtraction yields 32767. finally, this result is converted to the T_S16 type, which keeps the value 32767.
Thus, the statement with unsigned arithmetic may have a defined value in some situations where the statement with signed arithmetic does not have a value defined by the C standard.
(The statement with unsigned arithmetic still has undefined behavior if the final result is not representable in the T_S16 type, as when the final result is a number from 32768 to 65535 rather than from 0 to 32767.)

why there is no loss of precision for this floating point number assigned by sqrt()? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I want to understand how C handles the loss of precision for floating point number.
Here's my simple code:
#include <stdio.h>
#include <math.h>
int main ()
{
double a;
int i;
i = 7;
a = sqrt(i);
printf("i = %d, a = %lf\n", i, a);
printf("a * a = %lf\n", a*a);
a = 2.645751;
printf("a * a = %lf\n", a*a);
return(0);
}
Following is the result after cc
i = 7, a = 2.645751
a * a = 7.000000
a * a = 6.999998
If directly assigned a floating number which is 2.645751, the result of a * a looks understandable to me.
But if a is assigned sqrt(7), why there is no loss of precision for the output of a * a?
That is hard for me to understand.
Your confusion comes from what is actually held in a and what is printed as the default precision by printf. From man 3 printf "If the precision is missing, it is taken as 6". Therefore when you print with %lf (which should be simply %f as %f is already the format specifier for double) you are only seeing the value of a to the default 6-digit precision. (rounded)
a does not contain 2.645751 following your call to a = sqrt(i); -- that is just the default precision output by your printf statement. You can clearly see this just by specifying a longer precision for the output, e.g.
printf("i = %d, a = %.10f\n", i, a);
Output:
i = 7, a = 2.6457513111
So you need to keep clear what is contained in the actual double is most likely not what you see when you use printf with the default format specifier and default precision. double values (the 64-bits) represent a 1-bit sign bit, an 11-bit normalized exponent and a 52-bit mantissa. Not all numbers are capable of being represented exactly (just due to the limitation of bits to represent every possible number).
A good, but arguably rather dry to read, reference that goes into this a bit further is What Every Programmer Should Know About Floating-Point
Let me know if this helped your understanding, or whether you still have questions. We are happy to help further.
Your assigned a as double that have very long precision then the precision you assigned as hard coded. Thus, the precision error you got with the hard coded numbers is visible. At the same time, the precision error with sqrt() is not that much to visible, though it is not fully displayed with the printf().

right shifting the double variable [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
hi I want to do the followed task:
double time;
char array[6];
for(int index=0; index<6; index++){
array[index]=(char)(time>>(8*index));
}
but the error appears: expresion must have integral or unscoped enum
From ISO/IEC 9899:1999 (a.k.a. C99 standard):
6.5.7 Bitwise shift operators
Constraints
2 Each of the operands shall have integer type.
If you want to divide time by 2 to the power of (8*index), you can either:
Use pow() from math.h, or
Create an integer variable with value 1 << (8*index), then divide time by this variable
If you want to actually do a bit shift of the binary representation of the IEEE floating point number(1) (not that I understand why you would want to do that), you can do the following:
uint64_t x = *(uint64_t *)&time;
array[index]=(char)(x>>(8*index));
(1): Assuming your implementation uses IEEE floating point
Right shifting a float or double is almost certainly not what you meant to do, as the data representation is not one that would be affected by right shift as division by a power of 2.
You cannot use right-shifting operator for double variable.

Resources