ROUNDUP是什么?在C++中它有什么作用?

3

有人能解释一下这是什么意思吗?

#define ROUNDUP(n,width) (((n) + (width) - 1) & ~unsigned((width) - 1))

2
如果这是 C++,最好使用内联函数来实现这一点,而不是宏。 - bobbymcr
关于宏的典型问题,请参考http://www.parashift.com/c++-faq-lite/inline-functions.html。 - jamesdlin
1
ROUNDUP(n, x++)做什么?它会将x增加两次!内联函数没有这个问题。此外,看看STingRaySC的答案-宏可以传递任何东西。函数有类型。如果ROUNDUP是一个函数,那么STingRaySC的例子就无法编译。 (虽然我不确定它作为宏是否也能编译,但通常宏的无类型特性是一个问题)。除其他原因外,宏是邪恶的。 - tony
4个回答

6
如果提供的宽度是2的偶数次幂(如2、4、8、16、32等),则将返回一个大于或等于n的多个宽度的数字,该数字是满足该条件的最小值。 因此,当宽度= 16时; 5-> 16, 7-> 16, 15-> 16, 16-> 16, 17-> 32, 18-> 32等。请注意,&=按位与,〜=按位补码,并且在处理示例时应仅使用二进制表示。

请注意,宽度 必须 是2的幂...有一些情况下,四舍五入似乎适用于其他宽度(例如,对于n <5,四舍五入宽度3有效),但仅在一些奇怪的边角情况下。 - Sam Post
1
可爱的托尼 :-) 由于2^(1.58496298..) = 3(假设),我认为添加额外的限定符以指示排除该类型的2的幂是合理的。我认为“2的偶次幂”是一种常见但口语化的方式。抱歉对一个幽默评论作出了学究式的回复 :-). - Bill Forster
@Bill,我原本以为你把1排除在外了;因为这会使得~unsigned((width) - 1)等于0,从而使整个结果为0。 - JPvdMerwe
@JPvdMerwe 不,我认为我们可以包括1,因为掩码不是0,而是~0(0的补码,即全1),宏因此成为无操作,即n->n,这正如您所期望的那样(将其舍入到最接近的1的倍数=什么也不做)。 - Bill Forster
你说得对,我把运算符的顺序搞混了。当 width = 0 时,才会发生我所说的情况。 - JPvdMerwe

2

这段代码定义了一个名为ROUNDUP的宏,它接受两个参数nwidth,并返回值(n + width - 1) & ~unsigned(width - 1)

:)

如果您认为自己知道它的作用,请尝试一下:

std::string s("WTF");
std::complex<double> c(-11,5);
ROUNDUP(s, c);

2

它将 n 四舍五入到下一个“width” - 但我认为 width 需要是 2 的幂次方。

例如,当 width == 8,n = 5 时:

(5 + 8 - 1) & ~(7) = 12 & ~7 = 8

因此,5 被四舍五入到 8。任何介于 1 - 8 的数字都会被四舍五入到 8。9 到 16 会被四舍五入到 16。以此类推。(0 不会被四舍五入)


0

由于使用了unsigned,所以它在C中无法工作。只要width限制为2的幂次方,它就能实现以下功能:

 n width ROUNDUP(n,width)
----------------
 0   4    0
 1   4    4
 2   4    4
 3   4    4
 4   4    4
 5   4    8
 6   4    8
 7   4    8
 8   4    8
 9   4    12
10   4    12
11   4    12
12   4    12
13   4    16
14   4    16
15   4    16
16   4    16
17   4    20
18   4    20
19   4    20

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接