C++ 计算循环缓冲区中剩余空间的简化算法?

C++ 计算循环缓冲区中剩余空间的简化算法?,c++,circular-buffer,C++,Circular Buffer,我想知道是否有比这更简单(单一)的方法来计算循环缓冲区中的剩余空间 int remaining = (end > start) ? end-start : bufferSize - start + end; 失去条件: int remaining = (end + bufferSize - start - 1) % bufferSize + 1 编辑:-1和+1适用于end==start的情况。在这种情况下,此方法将假定缓

我想知道是否有比这更简单(单一)的方法来计算循环缓冲区中的剩余空间

int remaining = (end > start)
                ? end-start
                : bufferSize - start + end;
失去条件:

int remaining = (end + bufferSize - start - 1) % bufferSize + 1

编辑:
-1
+1
适用于
end==start
的情况。在这种情况下,此方法将假定缓冲区为空。根据缓冲区的具体实现,您可能需要对其进行调整,以避免一次过一次的情况。

如果您担心预测不佳的条件会减慢CPU的运行速度,您可以使用以下方法:

int remaining = (end - start) + (-((int) (end <= start)) & bufferSize);

<代码> int剩余=(结束-开始)+(-((int))(结尾< P>根据C++标准,第5.6节,第4段:

二进制/运算符产生商,二进制%运算符产生第一个表达式除以第二个表达式的余数。如果第二个操作数/或%为零,则行为未定义;否则(a/b)*b+a%b等于a。如果两个操作数都是非负的,则余数是非负的;如果不是,则余数的符号由实现定义

脚注表明,最好将商四舍五入到零,这将使余数为负数

<> P> >,<>代码(%-START)%BuffelSige方法不能可靠工作。C++没有模块化算法(除了在无符号整数类型提供的意义上)。 j_random_hacker推荐的方法是不同的,看起来不错,但我不知道它在简单性或速度方面是否有任何实际的改进。布尔值到int值的转换非常巧妙,但需要进行心理分析,而且根据编译器和机器的不同,摆弄可能比使用?更昂贵

我想你已经有了最简单最好的版本,我不会改变它。

int remaining = (end - start + bufferSize) % bufferSize;

13个令牌,我赢了吗?

如果您的循环缓冲区大小是2的幂,您可以通过让
start
end
表示虚拟流中的位置而不是循环缓冲区存储中的索引来做得更好。假设
start
end
是无符号的,则上述情况变为:

int remaining= bufferSize - (end - start);

实际上,从缓冲区中取出元素要复杂一些,但是如果使用2个大小的循环缓冲区(仅使用
bufferSize-1
屏蔽),开销通常就足够小了使循环缓冲区的所有其他逻辑更加简单和干净。此外,您可以使用所有元素,因为您不再担心
end==start

我知道的旧线程,但我认为这可能会有所帮助

不确定这个在C++中实现的速度,但是在RTL中,如果大小是n^ 2</p>,我们会这样做。

remaining = (end[n] ^ start[n])
            ? start[n-1:0] - end[n-1:0]
            : end[n-1:0] - start[n-1:0];


这是唯一的另一种选择,如果这是在一个类中,然后保持变量中的剩余空间。在C和C++中,%不是真正的模运算,而是余数。不同的是,当一个操作数是负的时,结果的符号是定义的实现。括号?添加一个abs()调用会减慢速度,tooAgreed--代码清晰度比任何一天都要快0.001%:)这很简单,尽管添加一个除法会使您的版本在大多数架构上变慢。因此,将缓冲区大小设为2.12年的幂次方,没有人提到这个计算是
大小
而不是
剩余的
:)需要修复的+2个代币
remaining = if (end[n] ^ start[n]) {
              start[n-1:0] - end[n-1:0]
            } else { 
              end[n-1:0] - start[n-1:0] 
            };