2013-01-23 21 views
2

在維基百科,它指出需要模運算來檢查循環緩衝區中的可用空間。然而在我的實施中,我只是這樣做:沒有模運算的循環緩衝區

static size_t bytes_used(const ringbuffer* rb) 
{ 
    int d = rb->writer - rb->reader; 

    if (d >= 0) return d; 

    return rb->size - abs(d); 
} 

static size_t bytes_free(const ringbuffer* rb) 
{ 
    return rb->size - (bytes_used(rb) + 1); 
} 

有沒有我忽略的東西,或者如何在這種情況下不需要它?

回答

4

你沒有忽視任何事情:bytes_used結束時的條件減法是一個「窮人的模」操作。它適用於不超過除數2倍的數字; 「真」模可以通過重複減法來實現。

更簡單的方法來獲得剩餘的尺寸如下:

(rb->writer - rb->reader + rb->size) % rb->size 

它採用模運算,避免條件執行。

P.S.你的實現也可以簡化:觀察最後一行d是否定的,所以abs(d) is the same as -d`。因此,你可以寫

return rb->size + d; 
+0

我試圖理解你說什麼。你能給我一個上面的代碼不起作用的數字,或者你的意思是「數字不超過2倍除數」的意思嗎? – Muis

+0

@Joshua考慮計算'A mod D'。如果您知道'A'嚴格小於'2 * D',那麼您可以將'A'與'D'進行比較,如果碰巧更大,則減去'D'來獲得結果;當'A dasblinkenlight