如何解决用无符号分子进行有符号除法
| 我正在尝试计算滚动平均值,并尝试获得一些优化,我简化了计算,因此只有一个除法。当值减小时,会出现一个点,当前值降低到小于平均值。此时平均跳升。我想这是因为除法是无符号的,并且分子的符号位被解释为一个巨大的无符号数。我只是不确定我需要在何处进行无符号转换以确保不会再次出现此问题。unsigned int AverageUsage;
unsigned int TotalUsage;
unsigned int incCount;
AverageUsage = (TotalUsage - AverageUsage)/++incCount + AverageUsage;
AverageUsage始终为正,但是当TotalUsage下降到AverageUsage以下时,我不确定该部门的期望
AverageUsage = (signed int)(TotalUsage - AverageUsage)/++incCount + AverageUsage;
将分子设置为有符号,但是我不确定除法将如何发生。
AverageUsage = (signed int)((signed int)(TotalUsage - AverageUsage)/++incCount) + AverageUsage;
应该可以工作(我可以保证此完整操作的结果永远不会为负),但是我担心incCount达到“看起来”为负的值的情况。
有没有希望解决此问题的简单方法:
不需要if语句
不需要QWORD
谢谢!
解决方法
您有2个选择。
使用浮点数学
我认为您还是想这样做以获得适当的平均水平。
没有混合的浮动/整数除法。因此,分子和分母都将转换为浮点数。
分子或分母是带符号的还是无符号的都没有关系。没有诸如无符号浮点之类的东西。分母incCount将转换为浮点,并完成完整的浮点除法。
使用整数除法并处理特殊情况
如果出于某种原因要保留整数除法,则分子和分母都必须是相同的有符号/无符号类型。
分子/分母均已签名
incCount将转换为带符号的数字。如果太大,它将看起来像一个负数,您的答案将是错误的。您必须测试此溢出。
分子/分母均未签名
您必须使分子无符号,并使用if()语句处理以下两种情况:
TotalUsage < AverageUsage
和TotalUsage > AverageUsage
。这里incCount可以使用整数位的全部范围,因为它将被视为无符号数字。
, C二进制运算(包括除法)的一般规则是将操作数都转换为相同类型,即:type5ѭ,unsigned int
,long
,unsigned long
,intmax_t
,uintmax_t
,float
,double
,long double
之一。如果两个操作数均为该列表中的类型,则它们都将转换为后一个。如果都不是,它们都将转换为to5ѭ
因此,在您的示例中:
AverageUsage = (signed int)(TotalUsage - AverageUsage)/++incCount + AverageUsage
如果incCount
是unsigned int
,那么您的强制转换无效-减法将转换为有符号的int,然后立即返回未识别的int并进行无符号除法。如果要签署部门,则需要:
AverageUsage = (int)(TotalUsage - AverageUsage)/(int)++incCount + AverageUsage
您要注意的是,如果incCount超过INT_MAX,可能会给您带来麻烦。
通常,用于除法的处理器指令仅指定一种类型,该类型用于两个操作数。当有一个特殊的指令用于不同类型的除法时,通常用于更大(双倍宽度)的除数,而不是不同的符号。
, 当然,请注意,这不是标准平均值。标准平均值为:
Averageusage = TotalUsage / ++incCount
假设(理想情况下)incCount是一些有用的定期增加值(例如秒)。
通常使用衰减平均值,例如:http://donlehmanjr.com/Science/03%20Decay%20Ave/032.htm(如果我正确翻译的话)是:
AverageUsage = TotalUsage / (incCount+1) + incCount/(incCount+1) * AverageUsage;
incCount++;
正如希玛德里(Himadri)所述,这些可能应该以浮点算法完成。
,如果可以预见并且对于TotalUsage unsigned long long或
double
将是适当的。
即使使用强制转换,如果TotalUsage new_output = alpha * previous_output + (1-alpha)*new_input; previous_output = new_output;其中
alpha
在0到0.9999之间。...
alpha
越接近1,则“越慢”的过滤器
您可以轻松地在浮点中执行此操作,也可以非常简单地以整数进行操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。