转载:http://stackoverflow.com/questions/1010922/question-about-round-up-macro

以下内容转载自stackoverflow关于 roundup 系列函数的讨论,已经解释的很详细了,不需要添加新内容。

 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))

With the above macro, could someone please help me on understanding the "(s)-1" part, why's that?

and also macros like:

 #define PAGE_ROUND_DOWN(x) (((ULONG_PTR)(x)) & (~(PAGE_SIZE-1)))
#define PAGE_ROUND_UP(x) ( (((ULONG_PTR)(x)) + PAGE_SIZE-1) & (~(PAGE_SIZE-1)) )

The ROUND_UP macro is relying on integer division to get the job done. It will only work if both parameters are integers. I'm assuming that N is the number to be rounded and S is the interval on which it should be rounded. That is, ROUND_UP(12, 5) should return 15, since 15 is the first interval of 5 larger than 12.

Imagine we were rounding down instead of up. In that case, the macro would simply be:

 #define ROUND_DOWN(N,S) ((N / S) * S)

ROUND_DOWN(12,5) would return 10, because (12/5) in integer division is 2, and 2*5 is 10. But we're not doing ROUND_DOWN, we're doing ROUND_UP. So before we do the integer division, we want to add as much as we can without losing accuracy. If we added S, it would work in almost every case; ROUND_UP(11,5) would become (((11+5) / 5) * 5), and since 16/5 in integer division is 3, we'd get 15.

The problem comes when we pass a number that's already rounded to the multiple specified.ROUND_UP(10, 5) would return 15, and that's wrong. So instead of adding S, we add S-1. This guarantees that we'll never push something up to the next "bucket" unnecessarily.

The PAGE_ macros have to do with binary math. We'll pretend we're dealing with 8-bit values for simplicity's sake. Let's assume that PAGE_SIZE is 0b00100000PAGE_SIZE-1 is thus 0b00011111~(PAGE_SIZE-1) is then 0b11100000.

A binary & will line up two binary numbers and leave a 1 anywhere that both numbers had a 1. Thus, if x was 0b01100111, the operation would go like this:

  0b01100111  (x)
& 0b11100000 (~(PAGE_SIZE-))
------------
0b01100000

You'll note that the operation really only zeroed-out the last 5 bits. That's all. But that was exactly that operation needed to round down to the nearest interval of PAGE_SIZE. Note that this only worked because PAGE_SIZE was exactly a power of 2. It's a bit like saying that for any arbitrary decimal number, you can round down to the nearest 100 simply by zeroing-out the last two digits. It works perfectly, and is really easy to do, but wouldn't work at all if you were trying to round to the nearest multiple of 76.

PAGE_ROUND_UP does the same thing, but it adds as much as it can to the page before cutting it off. It's kinda like how I can round up to the nearest multiple of 100 by adding 99 to any number and then zeroing-out the last two digits. (We add PAGE_SIZE-1 for the same reason we added S-1 above.)

Good luck with your virtual memory!

Using integer arithmetic, dividing always rounds down. To fix that, you add the largest possible number that won't affect the result if the original number was evenly divisible. For the number S, that largest possible number is S-1.

Rounding to a power of 2 is special, because you can do it with bit operations. A multiple of 2 will aways have a zero in the bottom bit, a multiple of 4 will always have zero in the bottom two bits, etc. The binary representation of a power of 2 is a single bit followed by a bunch of zeros; subtracting 1 will clear that bit, and set all the bits to the right. Inverting that value creates a bit mask with zeros in the places that need to be cleared. The & operator will clear those bits in your value, thus rounding the value down. The same trick of adding (PAGE_SIZE-1) to the original value causes it to round up instead of down.

linux tricks 之 roundup.的更多相关文章

  1. linux tricks 之 BUILD_BUG_ON_ZERO.

    ------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...

  2. linux tricks 之 FIELD_SIZEOF.

    ------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...

  3. linux tricks 之 container_of.

    转载:http://blog.chinaunix.net/uid-20608849-id-3027972.html 由于内核中定义了很多复杂的数据结构,而它们的实例中的成员在作为函数参数传递的时,函数 ...

  4. linux tricks 之 bitmap分析.

    ------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...

  5. linux tricks 之数据对齐。

    转载:http://blog.chinaunix.net/uid-20608849-id-3027953.html   内核为了保持最大的兼容性和代码灵活性,不可能直接对某个数据类型定义它的大小范围. ...

  6. linux tricks 之VA系列函数.

    VA函数(variable argument function),参数个数可变函数,又称可变参数函数.C/C++编程中,系统提供给编程人员的va函数很少.*printf()/*scanf()系列函数, ...

  7. linux tricks 之 typeof用法.

    typeof是gcc的扩展功能,比较简单,是用来取得参数类型,具体可参考gcc官网的解释. https://gcc.gnu.org/onlinedocs/gcc/Typeof.html ------- ...

  8. linux tricks 之 ALIGN解析.

    ------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...

  9. Linux tricks

    Environment Settings Path Globally set path is in /etc/profile; or the user's .bash_profile for part ...

随机推荐

  1. 一个令人蛋疼的 Microsoft.AspNet.FriendlyUrls

    我一个项目都基本上做完了,结果部署到我服务器的时候结果一直报404 找不到 一看global.asax有个路由注册的代码 public static void RegisterRoutes(Route ...

  2. [LeetCode] Word Ladder II

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

  3. 寻虫记:BOM头制造的冤案,无故多出空白行

    最近在做的一个网站发生了一个很诡异的BUG: 使用IE浏览页面时,一切都挺正常: 而使用Firefox浏览时,发现某些页面元素之间的距离比预期的要宽很多,HTML元素本身的hight.padding和 ...

  4. avalon框架,简单的MVVM

    今天我又要挑战一次一个高大上的公司了 但是看着jd有点忧伤了要求如下 基本要求:1.熟悉 HTML / CSS / JS 并有良好的代码风格:2.理解 Web 标准,语义化,可以解决主流浏览器及不同版 ...

  5. TYVJ1359 收入计划

    描述     高考结束后,同学们大都找到了一份临时工作,渴望挣得一些零用钱.从今天起,Matrix67将连续工作N天(1<=N<=100 000).每一天末他可以领取当天及前面若干天里没有 ...

  6. 建站时注意敏感词的添加_seo优化禁忌

    之前接手一个站点,网站标题中出现一个“三级医院”的词,虽然这个词在我们看来是没有问题的,医院评级中“三级医院”算是等级很高的,很多医院为了体现等级会在明显的地方着重加注.但是我们要考虑一下搜索引擎的分 ...

  7. [Effective JavaScript 笔记]第34条:在原型中存储方法

    js中完全有可能不借助原型进行编程.不用在其原型中定义任何的方法. 创建对象 构造函数法 所有属性和方法都在构造函数中定义 function User(name,pwd){ this.name=nam ...

  8. 5 个最受人喜爱的开源 Django 包

    导读 Django 围绕“可重用应用”的思想建立:自包含的包提供了可重复使用的特性.你可以将这些可重用应用组装起来,在加上适用于你的网站的特定代码,来搭建你自己的网站.Django 具有一个丰富多样的 ...

  9. UIImageView 动画 / UIImage 方向

    UIImage 方向 UIImage imageOrientation是相对当前屏幕的横竖屏来判断方向 如果本身是横屏, 照片也是横屏的话, 方向是正方向 BOOL b1 = (originalIma ...

  10. hiho一下第88周《Coordinates》

    题目大意 给定数字P,Q,求出所有P和Q的约数p,q能够组成的不重复数字对(p,q) 解题思路 作为本场比赛的第一题,本题的难度在于考察选手是否有基本的编程能力. 本题中需要求出P,Q所有约数组成的数 ...