为什么将 int 与 float 相除会得到 float?
Why does dividing a int with a float result in a float?
请问为什么会这样?
这只是C语言的东西吗?
我正在学习 cs50 课程。
#include <stdio.h>
int main(void)
{
int testInt = 5;
printf("%f", testInt / 4.0);
}
输出为 1.250000 -- 浮点值
Is this just a C language thing?
答案是“因为 C 语言就是这样定义操作的。”
在与另一个浮点值进行运算之前,将整数提升为浮点数在许多语言中很常见。
如果不是这样,就会出现许多意外的精度损失(或信息损失)错误。
计算表达式时,编译器需要确定表达式操作数的通用类型。
所以对于这个表达式
testInt / 4.0
(其中 4.0
是类型 double
的浮动常量)因为类型 double
的对象的值范围大于对象的值范围int
类型的对象然后编译器将 int
类型的对象转换为 double
类型的对象(因为进行这种转换比转换类型 double
到类型 int
的对象至少由于类型 double
的对象被截断)并执行操作。
此类转换称为通常的算术转换,并在 C 标准中进行了描述。
来自 C 标准(6.3.1.8 常用算术转换)
Otherwise, if the corresponding real type of either operand is double,
the other operand is converted, without change of type domain, to a
type whose corresponding real type is double.
Why does dividing a int with a float result in a float?
在C中,使用*, / +, -, %
这样的运算符,当2个操作数的类型不同时,通过将低位转换为高位来找到共同的。
int
排名低于float
,所以int
操作数被转换。
语言 可以 以不同方式指定 int * float
- 可能是某些 some_type mult_int_by_float(int, float)
操作。然而,这种方法会导致 许多 组合,并且仍然没有回答结果的类型。推广排名较低的类型更简单。
一种有N种类型的语言可以进行N*N种不同的乘法运算。用C的排序和转换的方法,更像是N个不同的乘法运算。
Is this just a C language thing?
是的。 TL/DR;版本是将narrower/less精确类型的操作数转换为与wider/more精确类型的操作数相同的类型,结果与[=]的操作数类型相同36=] 精确类型。以下是具体的规则集:
6.3.1.8 Usual arithmetic conversions
- Many operators that expect operands of arithmetic type cause conversions and yield result
types in a similar way. The purpose is to determine a common real type for the operands
and result. For the specified operands, each operand is converted, without change of type
domain, to a type whose corresponding real type is the common real type. Unless
explicitly stated otherwise, the common real type is also the corresponding real type of
the result, whose type domain is the type domain of the operands if they are the same,
and complex otherwise. This pattern is called the usual arithmetic conversions:
- First, if the corresponding real type of either operand is
long double
, the other
operand is converted, without change of type domain, to a type whose corresponding real type is long double
.
- Otherwise, if the corresponding real type of either operand is
double
, the other
operand is converted, without change of type domain, to a type whose
corresponding real type is double
.
- 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)
- Otherwise, the integer promotions are performed on both operands. Then the
following rules are applied to the promoted operands:
- If both operands have the same type, then no further conversion is needed.
- Otherwise, if both operands have signed integer types or both have unsigned
integer types, the operand with the type of lesser integer conversion rank is
converted to the type of the operand with greater rank.
Otherwise, if the operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type.
- Otherwise, if the type of the operand with signed integer type can represent
all of the values of the type of the operand with unsigned integer type, then
the operand with unsigned integer type is converted to the type of the
operand with signed integer type.
- Otherwise, both operands are converted to the unsigned integer type
corresponding to the type of the operand with signed integer type.
62) For example, addition of a double _Complex
and a float
entails just the conversion of the
float
operand to double
(and yields a double _Complex
result).
如果两个操作数都是整数,那么结果也是一个整数。如果任一操作数为浮点类型,则结果为浮点类型。
请问为什么会这样? 这只是C语言的东西吗?
我正在学习 cs50 课程。
#include <stdio.h>
int main(void)
{
int testInt = 5;
printf("%f", testInt / 4.0);
}
输出为 1.250000 -- 浮点值
Is this just a C language thing?
答案是“因为 C 语言就是这样定义操作的。”
在与另一个浮点值进行运算之前,将整数提升为浮点数在许多语言中很常见。
如果不是这样,就会出现许多意外的精度损失(或信息损失)错误。
计算表达式时,编译器需要确定表达式操作数的通用类型。
所以对于这个表达式
testInt / 4.0
(其中 4.0
是类型 double
的浮动常量)因为类型 double
的对象的值范围大于对象的值范围int
类型的对象然后编译器将 int
类型的对象转换为 double
类型的对象(因为进行这种转换比转换类型 double
到类型 int
的对象至少由于类型 double
的对象被截断)并执行操作。
此类转换称为通常的算术转换,并在 C 标准中进行了描述。
来自 C 标准(6.3.1.8 常用算术转换)
Otherwise, if the corresponding real type of either operand is double, the other operand is converted, without change of type domain, to a type whose corresponding real type is double.
Why does dividing a int with a float result in a float?
在C中,使用*, / +, -, %
这样的运算符,当2个操作数的类型不同时,通过将低位转换为高位来找到共同的。
int
排名低于float
,所以int
操作数被转换。
语言 可以 以不同方式指定 int * float
- 可能是某些 some_type mult_int_by_float(int, float)
操作。然而,这种方法会导致 许多 组合,并且仍然没有回答结果的类型。推广排名较低的类型更简单。
一种有N种类型的语言可以进行N*N种不同的乘法运算。用C的排序和转换的方法,更像是N个不同的乘法运算。
Is this just a C language thing?
是的。 TL/DR;版本是将narrower/less精确类型的操作数转换为与wider/more精确类型的操作数相同的类型,结果与[=]的操作数类型相同36=] 精确类型。以下是具体的规则集:
6.3.1.8 Usual arithmetic conversions
- Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result. For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type. Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is the type domain of the operands if they are the same, and complex otherwise. This pattern is called the usual arithmetic conversions:
- First, if the corresponding real type of either operand is
long double
, the other operand is converted, without change of type domain, to a type whose corresponding real type islong double
.- Otherwise, if the corresponding real type of either operand is
double
, the other operand is converted, without change of type domain, to a type whose corresponding real type isdouble
.- 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 isfloat
. 62)- Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
- If both operands have the same type, then no further conversion is needed.
- Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank. Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
- Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
- Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
62) For example, addition of adouble _Complex
and afloat
entails just the conversion of thefloat
operand todouble
(and yields adouble _Complex
result).
如果两个操作数都是整数,那么结果也是一个整数。如果任一操作数为浮点类型,则结果为浮点类型。