Efficient overflow-immune arithmetic mean in C/C++(C/C++中高效的溢出免疫算术平均值)
本文介绍了C/C++中高效的溢出免疫算术平均值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
两个无符号整数的算术平均值定义为:
mean = (a+b)/2
在C/C++中直接实现它可能会溢出并产生错误的结果。正确的实现可以避免这种情况。一种编码方式可能是:
mean = a/2 + b/2 + (a%2 + b%2)/2
但这会使用典型的编译器生成相当多的代码。在汇编程序中,这通常可以更高效地完成。例如,x86可以通过以下方式做到这一点(汇编伪代码,我希望您明白这一点):
ADD a,b ; addition, leaving the overflow condition in the carry bit
RCR a,1 ; rotate right through carry, effectively a division by 2
在这两条指令之后,结果在a
中,剩余的除法在进位位中。如果需要正确的舍入,则第三条ADC
指令必须将进位加到结果中。
请注意,使用的是RCR指令,它通过进位循环寄存器。在我们的例子中,它是旋转一个位置,因此前一个进位成为寄存器中的最高有效位,而新的进位保存寄存器中的前一个LSB。MSVC似乎甚至没有为此指令提供内部函数。
有没有一种已知的C/C++模式可以被优化编译器识别,从而生成如此高效的代码?或者,更广泛地说,有没有一种合理的方法来在C/C++源代码级别编程,以便编译器使用进位位来优化生成的代码?
编辑:
关于std::midpoint
:https://www.youtube.com/watch?v=sBtAGxBh-XI
哇!
EDIT2:Great discussion on Microsoft blog
推荐答案
以下方法可避免溢出,并应在不依赖非标准功能的情况下产生相当高效的汇编(example):
mean = (a&b) + (a^b)/2;
这篇关于C/C++中高效的溢出免疫算术平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:C/C++中高效的溢出免疫算术平均值
基础教程推荐
猜你喜欢
- 运算符重载的基本规则和习语是什么? 2022-10-31
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 设计字符串本地化的最佳方法 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- C++,'if' 表达式中的变量声明 2021-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01