| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 659 人关注过本帖, 1 人收藏
标题:给一个10进制数,如何输出2进制数中1的个数?
只看楼主 加入收藏
zlyc
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2015-10-19
结帖率:0
收藏(1)
已结贴  问题点数:20 回复次数:8 
给一个10进制数,如何输出2进制数中1的个数?
给一个10进制数,如何输出2进制数中1的个数?
搜索更多相关主题的帖子: 如何 
2015-10-19 20:52
lzl123321
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:41
专家分:148
注 册:2015-10-15
收藏
得分:4 
第一眼看起来觉得好容易,但仔细想想你这个十进制数没有限定正,负,整数,浮点数,小白的我表示无力啊!!
等大神!!!
2015-10-20 03:04
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:4 
程序代码:
#include <stdio.h>
#include <conio.h>

void Show_Byte(unsigned char ch)
{
    char buffer[8];
    unsigned char mask = 1;
    for (size_t index = sizeof(buffer); index > 0; --index)
    {
        buffer[index - 1] = ((ch & mask) == mask) + '0';
        mask <<= 1;
    }
    for (size_t index = 0; index < sizeof(buffer); ++index)
    {
        putchar(buffer[index]);
    }
}

int main()
{
    unsigned char* p;

    int a = 1000;
    p = (unsigned char*)&a;
    for (size_t index = 0; index < sizeof(a); ++index)
    {
        Show_Byte(*p++);
        putchar(' ');
    }
    putchar('\n');

    double b = 1000;
    p = (unsigned char*)&b;
    for (size_t index = 0; index < sizeof(b); ++index)
    {
        Show_Byte(*p++);
        putchar(' ');
    }
    putchar('\n');

    float c = 1000;
    p = (unsigned char*)&c;
    for (size_t index = 0; index < sizeof(c); ++index)
    {
        Show_Byte(*p++);
        putchar(' ');
    }
    putchar('\n');

    _getch();
    return 0;
}


注意:這是按數據在内存的順序輸出,但不同的機器有不同的數據結構,intel的處理器中,整數是低位在前、高位在後的,所以閲讀時,應把前面2個字節(16位二進制)挪到後面。

這揭示了一個編程陷阱:很多C程序員自以爲能夠對數據照X光,覺得瞭解數據的内存佈局,就隨意拆解完整的數據,按字節去解析和使用各部分。這種做法其實很危險,因爲不同的機器可能有不同的結構和數據解析機制,你如習慣某種機器高位在前,總寫那樣的代碼,就會忽略可移植性,到別的機器上出錯。資深的C程序員,對大頭、小頭振振有詞,知道在内置數據類型有所避忌,但到了結構體的數據結構,就會經常踩這個陷阱,他們會想當然機器的真實内存佈局是自己代碼寫的那樣,但事實上,除了大小頭之外,還有對齊的問題,甚至,某些編譯器會做優化,調整你代碼中結構體的數據順序,以獲取更緊密高效的内存佈局,這些都不是你自以爲那樣可控的。所以,不要養成肢解數據的習慣!

[此贴子已经被作者于2015-10-20 04:36编辑过]


授人以渔,不授人以鱼。
2015-10-20 04:17
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:4 
回复 2楼 lzl123321
最主要的是没有限定这个十进制的范围,如果输入 999999999999999999999999999999999999999999999999999999999999999999999999999999999999 时,连 unsigned long long 都存不下,那就是另一种完全不同的解法了。

如果在整数范围内,可以用移位的方式快速累加,比如一个32bits的整型,一位一位的判断的话,需要32次;用移位的方式可以缩减到 log2(32)=5 次
程序代码:
uint32_t func( uint32_t x )
{
    x = (x & 0x55555555UL) + ((x >> 1) & 0x55555555UL);
    x = (x & 0x33333333UL) + ((x >> 2) & 0x33333333UL);
    x = (x & 0x0f0f0f0fUL) + ((x >> 4) & 0x0f0f0f0fUL);
    x = (x & 0x00ff00ffUL) + ((x >> 8) & 0x00ff00ffUL);
    x = (x & 0x0000ffffUL) + ((x >> 16) & 0x0000ffffUL);
    return x;
}

2015-10-21 12:29
诸葛欧阳
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:流年
等 级:贵宾
威 望:82
帖 子:2790
专家分:14619
注 册:2014-10-16
收藏
得分:4 
回复 4楼 rjsp
这个思路相当好

一片落叶掉进了回忆的流年。
2015-10-21 16:18
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
回复 6楼 边小白
简单些,假设只有4个bits,分别是 abcd
abcd并上二进制的0101得到0b0d,abcd右移一位并上0101得到0a0c
将 0b0d 和 0a0c 相加就得到 (a+b)(c+d)
也就是这一步之后,ab这两bits上值变成了ab这两bits上原来1的数目;同理,cd这两bits上的值变成了原先cd上1的数目
也就是一步操作同时执行了两个加法
相邻的1bit和1bit加完后,再相邻的2bits和2bits相加,4bits和4bits相加,8bits和8bits相加……

以 01101110 为例
第一步相邻的1bit相加,也就是 (0 1) (1 0) (1 1) (1 0) 这四组组内相加得 01 01 10 01
第二步相邻的2bit相加,也就是 (01 01) (10 01) 这两组组内相加得 0010 0011
第三步相邻的4bit相加,也就是 (0010 0011) 这一组组内相加得 00000101,十进制就是5
2015-10-22 10:30
lzl123321
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:41
专家分:148
注 册:2015-10-15
收藏
得分:0 
回复 7楼 rjsp
不明觉厉啊!!
2015-10-22 12:20
快速回复:给一个10进制数,如何输出2进制数中1的个数?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025827 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved