gpt4 book ai didi

c - 不同数据类型的乘法变量的顺序是否会导致不同的结果?

转载 作者:太空狗 更新时间:2023-10-29 15:23:22 28 4
gpt4 key购买 nike

假设我有 3 个变量:longintshort

long  l; 
int i;
short s;
long lsum;

如果这是纯数学,因为乘法具有交换性质,所以这些变量的顺序无关紧要。

 l * i * s = i * s * l = s * i * l.

lsum 成为这 3 个变量相乘的容器。

在 C 中,是否会出现这些变量的特定顺序导致不同结果的情况?

如果在这种情况下顺序确实很重要,不一定来自这个例子,那会是什么?

最佳答案

由于整数提升,顺序确实很重要。

当应用算术运算符时,如果它的等级小于 int(例如 char),它的每个操作数首先被提升为 int)。如果这些操作数中的一个仍然具有更高的等级(例如 long),则提升较小的。

来自 C standard 的第 6.3.1 节:

2 The following may be used in an expression wherever an int or unsigned int may be used:

  • An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.

  • A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.

摘自第 6.3.1.8 节:

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.

举个例子(假设sizeof(int)是4,sizeof(long)是8):

int i;
short s;
long l, result;

i = 0x10000000;
s = 0x10;
l = 0x10000000;

result = s * i * l;
printf("s * i * l=%lx\n", result);
result = l * i * s;
printf("l * i * s=%lx\n", result);

输出:

s * i * l=0
l * i * s=1000000000000000

在这个例子中,s * i 首先被评估。 s 的值被提升为 int,然后将两个 int 值相乘。此时发生溢出,取消未定义的行为。然后将结果提升为 long 并乘以 l,结果为 long 类型。

在后一种情况下,首先评估 l * ii 的值被提升为 long,然后将两个 long 值相乘,不会发生溢出.然后将结果乘以 s,首先将其提升为 long。同样,结果不会溢出。

在这种情况下,我建议将最左边的操作数转换为 long,以便所有其他操作数都提升为该类型。如果您有带括号的子表达式,您可能还需要在那里应用强制转换,具体取决于您想要的结果。

关于c - 不同数据类型的乘法变量的顺序是否会导致不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44055758/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com