带无符号分子的带符号除法

Gdo*_*ogg 7 c embedded signed

我正在尝试计算滚动平均值,并试图获得并优化一点,我简化了计算,因此只有一个除法.当值减小时,存在当前值降低到小于平均值的点.此时平均跳跃.我想这是因为除法是无符号的,我的分子符号位被解释为一个大的无符号数.我只是不确定我需要在哪里投贴无符号以确保此问题不再出现.

unsigned int AverageUsage;
unsigned int TotalUsage;
unsigned int incCount;

    AverageUsage = (TotalUsage - AverageUsage)/++incCount + AverageUsage;
Run Code Online (Sandbox Code Playgroud)

AverageUsage将始终为正,但当TotalUsage低于AverageUsage时,我不确定该部门会有什么期望

    AverageUsage = (signed int)(TotalUsage - AverageUsage)/++incCount + AverageUsage;
Run Code Online (Sandbox Code Playgroud)

将分子设置为已签名,但我不确定如何进行除法.

    AverageUsage =  (signed int)((signed int)(TotalUsage - AverageUsage)/++incCount) + AverageUsage;
Run Code Online (Sandbox Code Playgroud)

应该工作(我可以保证这个完整操作的结果永远不会是负面的),但我担心incCount达到"看起来"负面的值的情况.

是否有一个简单的解决方案,希望:

  • 不需要if语句
  • 不需要QWORD

谢谢!

Chr*_*odd 5

C二元OPS(包括分裂)的一般规则是,操作数都将被转换为相同的类型,这是以下之一:int,unsigned int,long,unsigned long,intmax_t,uintmax_t,float,double,long double.如果两个操作数都是该列表中的类型,则它们都将转换为后一个操作数.如果两者都不是,那么它们都将被转换为int

所以在你的例子中:

AverageUsage = (signed int)(TotalUsage - AverageUsage)/++incCount + AverageUsage
Run Code Online (Sandbox Code Playgroud)

if incCountis unsigned int,那么你的强制转换没有效果 - 减法将转换为signed int,然后再回到unisgned int,并且将完成无符号除法.如果您想要签名的部门,您需要:

AverageUsage = (int)(TotalUsage - AverageUsage)/(int)++incCount + AverageUsage
Run Code Online (Sandbox Code Playgroud)

正如您所说,如果incCount超过INT_MAX,您可能会遇到麻烦.

通常,用于除法的处理器指令仅指定一种类型,其用于两个操作数.当存在用于具有不同类型的除法的特殊指令时,其通常用于较大(双倍宽度)的被除数,而不是不同的符号.


Him*_*ury 4

你有两个选择。

使用浮点数学

我认为无论如何你都想这样做以获得适当的平均值。

不存在混合浮点数/整数除法这样的东西。因此,分子和分母都将转换为浮点数。

分子或分母是有符号还是无符号并不重要。不存在无符号浮点数这样的东西。分母 incCount 将转换为浮点型,并进行完整的浮点除法。

使用整数除法并处理特殊情况

如果出于某种原因您想保留整数除法,则分子和分母必须是相同的有符号/无符号类型。

分子/分母均带符号

incCount 将转换为有符号数。如果它太大,那么它看起来就像一个负数,你的答案就会是错误的。您必须测试此溢出。

分子/分母都是无符号的

您必须使分子无符号并使用 if () 语句来处理两种情况:TotalUsage < AverageUsageTotalUsage > AverageUsage。这里 incCount 可以使用整数位的全部范围,因为它将被视为无符号数。