klib库下的kroundup32(二进制的四舍五入)算法

blackcat 发布于10月前 阅读867次
0 条评论

出自开源库klib(一个c语言的标准库)中。github地址

一. 函数解释

  • 对于32位的机器的二进制数字进行向上的四舍五入

  • 例如 7(111)->8(1000), 12(1100)->(10000)

#include <stdio.h>
#include <stdint.h>
#ifndef kroundup32
#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
#endif

int main(int argc, char const *argv[])
{
    int x=7; 
    kroundup32(a);
    printf("%d\n",x); // 显示8(1000)
    return 0;
}

二. 解释说明

1. 举例 00000000000000000101001011011011

2. 步骤1 --x

数字减一,避免进一步的四舍五入。

例如 100不向1000进行四舍五入的进位,10000不向100000进行四舍五入的进位。

3. 步骤2 通过右移和"|"运算, 分别把一"补"入到每一个位置,直到每一个位置都是"1"为止

1. 右移1位 -> 保障前2个位置都变成1
00000000000000000101001011011010
|
 0000000000000000010100101101100
---------------------------------
00000000000000000111001011011010

2. 因为为上一次的"|"运算,使得前2位都是"1"

所以这次右移2位 -> 保障前4个位置都变成1
00000000000000000111001011011010
|
  000000000000000001110010110110
---------------------------------
00000000000000000111111011111111

3. 同上 因为为上一次的"|"运算,使得前4位都是"1"

所以这次右移4位 -> 保障前8个位置都变成1
00000000000000000111111011111111
|
    0000000000000000011111101111
---------------------------------
00000000000000000111111111111111
4. 同上 因为为上一次的"|"运算,使得前8位都是"1"

右移8位 -> 保障前16个位置都变成1
00000000000000000111111111111111
|
        000000000000000001111111
---------------------------------
00000000000000000111111111111111
5.  同上 因为为上一次的"|"运算,使得前16位都是"1" 

右移16位 -> 保障前32个位置都变成1
00000000000000000111111111111111
|
                0000000000000000
---------------------------------
00000000000000000111111111111111

4. 步骤3 ++x

以为上一步中将这个数字的所有为止都变成了1,所以"+1"后就完成了进位的工作

查看原文: klib库下的kroundup32(二进制的四舍五入)算法

  • blackfrog
  • tinytiger
  • greenswan
需要 登录 后回复方可回复, 如果你还没有账号你可以 注册 一个帐号。