gpt4 book ai didi

c# - 这个按位表达式有更好的逻辑吗?

转载 作者:太空宇宙 更新时间:2023-11-04 14:19:30 24 4
gpt4 key购买 nike

我正在开发一个程序来处理使用散列的文件。数据被分成长度为 0x1000 的 block 。我需要计算具有特定起始和结束偏移覆盖的段的 block 数量。

例如,如果段的起始偏移量为 0x2000,结束位置为 0x3523,则表示它占用了两个 block ,0x2000 和 0x3000。它不占用数据 block 中的完整 0x2000 字节,但当它在其中时被认为是“占用一个 block ”。我的第一个想法是:

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

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

无论如何,逻辑是有缺陷的,因为,这就是我遇到的情况,如果起始偏移量是 0x3D8A,结束偏移量是 0x671D,则两者之间的差值是 0x2993。四舍五入为 0x3000,或三个 block 。该段实际上占用了四个,0x3000、0x4000、0x5000和0x6000。所以我的下一列火车,不幸的是我的最后一列火车,是找到该段所在的第一个 block 的偏移量与该段不在的第一个 block 的偏移量之间的差异。

对于 0x3D8A 和 0x671D,这将我带到 (0x7000 - 0x3000) >> 0xC,它成功地产生了正确数量的 block ,4。我写它的方式是我想要改进的,即:

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

我知道我已经把一个简单的问题复杂化了,但是我的小脑袋想不出如何把它写得更好。

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

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

虽然看起来还不完整。

edit 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 的 bitfiddling 等价物是 >> 12

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

正如@Ron 指出的那样,您需要一个条件来区分最后一个(“one-past”) block 是否为空,并在后一种情况下将 block 计数递增 1。

关于c# - 这个按位表达式有更好的逻辑吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8721963/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com