转载: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 0b00100000. PAGE_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. C语言计算任意数的任意次方

    #include "stdio.h" #include"stdlib.h" #define max 500 void yiwei(int *a,int n,in ...

  2. 说说Java中的枚举(一)

    在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的.例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”. ...

  3. MySQL日期数据类型、MySQL时间类型使用总结

    MySQL:MySQL日期数据类型.MySQL时间类型使用总结 MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型 存储空间 日期格式 日期范围 ------------ --- ...

  4. 陷阱~EF中的Update与Insert共用一个数据上下文

    事情是这样的,有一个列表,里面有很多用户信息,可能会有重复的用户,将这个列表的用户插入到数据表中,如果用户已经存在,就更新这个用户的FillTimes 字段,让它加1,使用的底层ORM是entity ...

  5. vssver2.scc 文件是干啥的?

    idcdpi源文件下的tools下有一个文件    vssver2.scc     vssver2.scc是什么文件 首先,先来个名词解释:Microsoft Visual Source Safe是美 ...

  6. Entity Framework ModelFirst尝试

    前言 Model First我们称之为“模型优先”,这里的模型指的是“ADO.NET Entity Framework Data Model”,此时你的应用并没有设计相关数据库,在Visual Stu ...

  7. PHP数据访问

    <?php //作业:把INFO表查出来用表格显示 //1.造一个连接对象 $db = new MySQLi("localhost","root",&qu ...

  8. 不用插件直接同步wordpress文章日志到新浪微博

    社会化媒体营销可以为网站带来流量,如果你的社会化媒体账号的粉丝技术够大的话!社会化媒体营销国内做得比较好的算新浪微博了.那么我们要怎样同步wordpress文章日志到新浪微博呢?当然你可以使用插件来实 ...

  9. Crashing Robots(imitate)

    Crashing Robots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8124   Accepted: 3528 D ...

  10. iphone数据存储之-- Core Data的使用(一)

    http://www.cnblogs.com/xiaodao/archive/2012/10/08/2715477.html 一.概念 1.Core Data 是数据持久化存储的最佳方式 2.数据最终 ...