二进制中1的个数,解题总结,深入理解整型数据的存储

博客介绍了如何计算一个整数二进制表示中1的个数,探讨了补码表示的负数和位运算在解题中的应用。通过两种方法,包括直接模拟补码转换和位运算技巧,阐述了对整型数据存储的深入理解。同时,文章指出Java中int类型的数据范围,并解释了正负数表示的边界原因。
摘要由CSDN通过智能技术生成


题目:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

这是一道并不复杂的,很基础的题。但是通过这道题,我更深刻的了解到了:

  1. java对于整型数据的处理。
  2. 位运算巧妙。

作为一个编程菜鸟,看题之后,我就知道,利用位运算是最为恰当的方式,但是碍于对位运算不甚熟
悉,因此也望而却步,最后使用了笨笨的呆呆的方式。不过解题思路虽然呆头呆脑,但也正是这种呆头呆脑,让我学习了更多知识(这里绝对没有“不呆头呆脑就学习不到知识的意思😊”),所谓塞翁失马,焉知非福,也正是这个道理。

我呆头呆脑的方式😜: 完全模拟整数到二进制补码的过程

一大波僵尸代码:

 public int NumberOf1(int n) {
        int p=n;                         //思路: 
        int q=0;						 //   1. 当n==0,返回0;
        int count=0;					 //   2. 当n>0,老实的求余数。
        if(n==0) return 0;               //   3. 当n<0,这里就复杂了,一句话就是模拟
        else if(n>0){                    //      一个负数从转为正数,到转为反码数,再
            while(p>0){					 //      到转为补数的笨过程。
                q=p%2;
                if(q==1) count++;
                p/=2;
            }
        }else{
            if(n==-2147483648) return 1; 
            p=-p;
            int temp=1;
            int cishu=31;
            while(p>0){
                q=p%2;
                q= q==0?1+temp:temp;
                if(q==0) {
                    temp=0;
                }else if(q==1){
                    temp=0;
                    count++;
                }else{
                    temp=1;
                }
                p/=2;
                cishu--;
            }
            count=count+cishu+1;
        }
        return count;
    }

大神解锁方式👏👏👏:一切都是位运算

其实位运算在这导题中另一个好处就是,对于整形数据的存储和运算本身就是使用的补码方式,因此不需要再去计较负数的补码到底是多少。

方式一:最牛叉的看这里!!!

下面这种方式是最牛逼的 非常简单高效,代码已经减少到不能再少了,太棒了!!! 位运算的魅力体现的淋漓尽致!!!

int  NumberOf1(int n) {
         int count=0;
         while(n)
             {
             count++;
             n=n&(n-1);
         }
         return count;
     }

n&(n-1) ,就是它,一切的罪魁祸首。(n-1)将最右边的1 变为 0,后边的0 则便为1 ,再通过 与自身相或,其他位不变,这个1到右边所有位都将会变为0,如:
11100 减后 11011 & 11100 = 11000

方式二:

下面两种方式交之上一种老实些,两种方式区别不大,就像一个走后门,一个走前门。
具体思路分别打个例子就大概知道了,比如第一种:
第一次: 10011 & 00001 = 00001 count++;
第二次: 10011 & 00010 = 00010 count++;
第三次: 10011 & 00100 = 00000
第四次: 10011 & 01000 = 00000
第五次: 10011 & 10000 = 10000 count++;

class Solution {
public:
     int  NumberOf1(int n) {
         int falg=1;
         int count=0;
         while(falg){
             if(n&falg) count++;
             falg=falg<<1;
         }
         return count;
     }
};
public class Solution {
    public int NumberOf1(int n) {
      int a=0;
      if(n==0)return 0;
      while(n !=0){
          if((n&1)>0){
             a++; 
          }
          n=n>>>1;
      }
        return a;
    }
}

从本题中获得的对整型数据存储的深入理解

首先 int 类型是4个字节来装载,所以共32位,除开符号位有31位用于数据表达。
正数表达的范围:1~2^31-1 也就是 1~ 2 147 783 647
负数表达的范围:-1~-2^31-1 也就是-1~ -2 147 783 648
为什么差1呢? 问题出在 0 上。
因为 0 是作为正数存储的,因此正数加上0就是2147783648个数字。
而对负数就没有0 ,因此从-1存储到-2147783648,
这时对于补码 -1占的就是1111111111111111111111111111111
而-2147783648占的就是1000000000000000000000000000
具体个数别介意,意思意思就行😅

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值