繁体   English   中英

这种按位表达的逻辑更好吗?

[英]Better logic for this bitwise expression?

我正在开发一个处理使用哈希的文件的程序。 数据分为长度为0x1000的块。 我需要计算具有一定起始和结束偏移量覆盖的线段的块数。

例如,如果段的起始偏移为0x2000,结束为0x3523,则意味着它将占用两个块:0x2000和0x3000。 它不会占用数据块中的完整0x2000字节,但是在其内部时,它被视为“占用了一块”。 我首先想到的是:

( ( EndingOffset - StartingOffset ) + 0xFFF ) >> 0xC

这等效于Math.Ceil((EndingOffset - StartingOffset) / 0x1000) ,但是我是按位运算符的新手,并且喜欢使用它们的挑战。

无论如何,逻辑是有缺陷的,例如,这就是我的情况,如果起始偏移为0x3D8A,结束偏移为0x671D,则两者之间的差为0x2993。 取整为0x3000或三个块。 该段实际上占用了四个,分别为0x3000、0x4000、0x5000和0x6000。 所以我的下一班火车,很不幸的是我的下一班火车,是找到该分段所在的第一个程序段的偏移量与该分段不在的第一个程序块的偏移量之间的差。

使用0x3D8A和0x671D,这使我进入(0x7000 - 0x3000) >> 0xC ,它成功地产生了正确数量的块。4。我编写它的方式就是我要改进的,这是:

BlockSize = ((((OffsetEnd + 0xFFF) >> 12) + 1) - ((OffsetStart + 0xFFF) >> 12));

我知道我已经使一个简单的问题复杂化了,但是我无法全神贯注于如何更好地编写它。

编辑:这很尴尬。 我不知道我是怎么来的

(((OffsetEnd + 0xFFF) >> 12) - (OffsetStart >> 12));

仍然似乎还不完整。

编辑2:对不起,忘了提到结束偏移量是排他的,不是排他的,并且是该段最后一个字节之后的位置,表示:

(((OffsetEnd - 1 + 0xFFF) >> 12) - (OffsetStart >> 12));

编辑3:离开Kerek的答案,我得出以下结论:

BlockSize = 1 + (offsetEnd - 1 >> 12) - (offsetStart >> 12);

..或,从0开始计数,

BlockSize = (offsetEnd - 1 >> 12) - (offsetStart >> 12);

编辑4:忘记从零开始计数,我坚持:

BlockSize = 1 + (offsetEnd - 1 >> 12) - (offsetStart >> 12);

假设您的数据范围为[start,end) ,这很简单:

unsigned int start_block = start_offset / 0x1000;
unsigned int end_block = end_offset / 0x1000;

unsigned int number_of_blocks = end_block - start_block + (end_offset > start_offset && end_offset % 0x1000 > 0 ? 1 : 0);

我想/ 0x1000的位纠缠等效项是>> 12

您的数据将占据块范围[start_block,end_block)。 请注意,块0为[0x0000,0x1000),块1为[0x1000,0x2000)等。

正如@Ron所指出的,您将需要一个条件来区分最后一个(“过去”)块是否为空,并在后一种情况下将块计数加1。

((EndingOffset-StartingOffset)+ 0xFFF)>> 0xC +(StartingOffset&〜(0xFFF)!= 0)

这将使您的开头很简洁,并且将查看StartingOffset是否落在块边界上。 如果不是,请添加1。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM