• C语言 #define _INTSIZEOF(n)对齐的算法


    1.  数学规则:
    对于任意两个正整数 X, Y,假设Y>=X, 总是存在两个整数 q /*Quotient缩写*/, r /*Remainder缩写*/ 使得
    等式 Y = q*X + r 成立, 要求 0 <= r < X, 则q(商), r(余数) 是唯一确定的。
    商: q = [Y/X] /*[]:取整函数*/
    余数: r = Y - q*X 推倒出 r = Y - [Y/X]*X.

    2.  自定义规则:
        定义一种Y的取值规则,要求让Y是能整除X,且是最接近X的整数
        
    2.1 地板法:
    若 0 =< r < X, 取 Y = q*X, 
    c语言为我们提供整形除法,所以地板法容易实现: q = Y/X /*取商*/, r = Y%X /*取余数*/
    必杀技巧:如果X值恰巧是2^n,那么直接左移n位 q = Y >> n , r = Y&(X-1);

    2.2 天花板法:
    若 0 < r <= X, 取 Y = (q+1)*X. 

    3.  现在我们问题是,如何利用C语言实现这个天花板法?
     Y     X   x/y   x%y    地板  天花板
     0 ->  5 -> 0 ->  0 ->   0 ->   5
     1 ->  5 -> 0 ->  1 ->   0 ->   5
     2 ->  5 -> 0 ->  2 ->   0 ->   5
     3 ->  5 -> 0 ->  3 ->   0 ->   5
     4 ->  5 -> 0 ->  4 ->   0 ->   5
     5 ->  5 -> 1 ->  0 ->   5 ->   5
     6 ->  5 -> 1 ->  1 ->   5 ->  10
     7 ->  5 -> 1 ->  2 ->   5 ->  10
     8 ->  5 -> 1 ->  3 ->   5 ->  10
     9 ->  5 -> 1 ->  4 ->   5 ->  10
    10 ->  5 -> 2 ->  0 ->  10 ->  10
    11 ->  5 -> 2 ->  1 ->  10 ->  15
    12 ->  5 -> 2 ->  2 ->  10 ->  15
    13 ->  5 -> 2 ->  3 ->  10 ->  15
    14 ->  5 -> 2 ->  4 ->  10 ->  15
    15 ->  5 -> 3 ->  0 ->  15 ->  15
    16 ->  5 -> 3 ->  1 ->  15 ->  20
    17 ->  5 -> 3 ->  2 ->  15 ->  20
    18 ->  5 -> 3 ->  3 ->  15 ->  20
    19 ->  5 -> 3 ->  4 ->  15 ->  20
    20 ->  5 -> 4 ->  0 ->  20 ->  20
    21 ->  5 -> 4 ->  1 ->  20 ->  25

    直接让商Q = Y/X + 1行不行?
    地板法:
    Y = {0,1,2,3,4} => q = 0 则 Q = 1
    Y = 5 => q = 1 则 Q = 2
    很明显不是我们想要的结果,我们希望Y = 5,Q = 1
    所以
    商Q = (Y-1)/X + 1
    Y=Q*X=((Y-1)/X + 1)*X = (Y+X-1)/X*X

    4.证明过程:

    ceiling的除法运算是只要余数不为0,商要进1,对于整型的Y/X而言只需Y+其最大的余数即可既ceiling = (Y+最大的余数)/X

    4.1   证明方法1:
    首先按照地板除Y/X,我们只能得到地板值,然后余数是r(从0到X-1),
    现在我们要求用地板除规则实现天花板除,那么势必要给Y值的基础上加上X,再地板除(Y+X)/X,这样商能多加1,注意此时余数不发生改变,仍为(0,1,2...X-1)
    但是天花板除法又规定,就是(Y+X)/X整除时,商不进位,那么我们让Y+X再减去1,即(Y+X-1)/X,则余数为(-1,0,1,2...X-2),原来余数为1的位置对应的数,现在整除了.也就是按照地板除规则,余数位(0,1,2...X-2),所对应的商都为0,至于-1对应的数,也就是原来能整除的数,已经去到上一轮了.

    当Y=nX时,(Y+X-1)/X=>(nX+X-1)/X不进位,
    当Y=nX+1时,(Y+X-1)/X=>(nX+1+X-1)/X=>n+1
    ...
    当Y=nX+X-1时 (Y+X-1)/X=>(nX+X-1+X-1)/X=>n+1
    当Y=nX+X时 (Y+X-1)/X=>(nX+X+X-1)/X=>n+1

    4.2   证明方法2:
    这也相当于把 Y 表示为:
    Y = q'*X + r', 其中 -X < r' <=0                //最大非正剩余   
    q'*X 是我们所求。

    关键是如何用 c 语言计算它。由于我们能处理标准的带余除法,所以可以把这个式子转换成一个标准的带余除法,然后加以处理:
    已知 Y = q'*X + r', 其中 -X < r' <=0 
    则 Y+X = q'*X + (X+r'),其中 0 < X+r' <= X            //最asx大正剩余
    则 Y+X-1 = q'*X + (X+r'-1), 其中 0 <= X+r'-1 所以 q'*X = [(Y+X-1)/X]*X 推倒出 q'*X = [(Y-1)/X]*X + X
    其中 q' = [(Y+X-1)/X] 推倒出 q' = [(Y-1)/X] +1

    5.用C语言计算(Y+X-1)/X*X

    若 X 是 2 的方幂, 比如 2^m,则除为右移 m 位,乘为左移 m 位。
    所以
    (Y+X-1)/X : 相当于右移 m 位
    (Y+X-1)/X*X : 相当于将上面的值再左移m位,也等价于将最低 m 个二进制位清0
    上面两句等价于
    (Y+X-1) & (~(X-1))
    假设X = 8 = 0b1000,则 X-1 = 0b0111,~(X-1) = 0b111...11000
    这样再与原来的值相与就清零了.

    6.这种算法主要可以用到内存对齐上

    如果数据总线是32根,那么每次只能取到4个字节的数据,可以使用该法方法,让地址总线每次都指向4的倍数的地址,


    #define _INTSIZEOF(n) - ★行云流水★ - 博客园问:#define _INTSIZEOF(n)((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) 说能够在某些系统中内存对齐.(估计是得到一个2 或https://www.cnblogs.com/cmembd/p/3190706.html

  • 相关阅读:
    图像实时采集系统
    算法每日一题(反转单链表)C语言版
    Redis的持久化策略(RDB、AOF、RDB-AOF混合持久化)
    【正则】二代身份证正则表达式
    动态规划算法
    网络的基本概念
    利用 docker 实现JMeter分布式压测
    Docker 基础使用(2) 镜像与容器
    跨平台命令行ssh终端工具tryssh详解
    select&epoll讲解(例:实现FTP文件上传下载)
  • 原文地址:https://blog.csdn.net/qq_50832904/article/details/126372615