负二进制表示法——“奋斗杯”编程大赛题目

   日期:2020-11-03     浏览:102    评论:0    
核心提示:负二进制表示法-“奋斗杯”编程大赛题目0、题目1、思考1.1 先试一个简单的值 161.2 再试一下题干中的值31.3 试一下特殊值-132 代码实现0、题目计算机里的数都是二进制表示,其实还有一种负二进制表示法,都不需要符号位。如 3 的负二进制表示法为 111,因为 (-2)2 + (-2)1 + (-2)0 = 4-2+1 = 3 。再如 -3 的负二进制表示法为 1101,因为 (-2)3 + (-2)2 + (-2)0 = -8+4+1 = -3 。要求输入一个整数,输出其负二进制表

负二进制表示法-“奋斗杯”编程大赛题目

  • 0、题目
  • 1、思考
    • 1.1 先试一个简单的值 16
    • 1.2 再试一下题干中的值3
    • 1.3 试一下特殊值-13
  • 2 代码实现go和java

0、题目

计算机里的数都是二进制表示,其实还有一种负二进制表示法,都不需要符号位。

如 3 的负二进制表示法为 111,因为 (-2)2 + (-2)1 + (-2)0 = 4-2+1 = 3

再如 -3 的负二进制表示法为 1101,因为 (-2)3 + (-2)2 + (-2)0 = -8+4+1 = -3

要求输入一个整数,输出其负二进制表示。

  • Golang
  • Java

1、思考

指数
0 (-2)0 1
1 (-2)1 -2
2 (-2)2 4
3 (-2)3 -8
4 (-2)4 16
5 (-2)5 -32

由表可知,负二进制理论上可以表示计算机位数范围内的任意整数值。
准备几个特殊的值备用,(0)10 = (0)-2 , (1)10 = (1)-2 , (-1)10 = (11)-2

首先回忆一下十进制转二进制的方法,除2取余倒着写,嗯,我们先试一下,看看能不能也用到负二进制的换算上。

1.1 先试一个简单的值 16

  • 16/(-2) = -8 ······ 0
  • -8/(-2) = 4 ······ 0
  • 4/(-2) = -2 ······ 0
  • -2/(-2) = 1 ······ 0

所以 (16)10 = (10000)-2 ,嗯,看起来好像没毛病。

1.2 再试一下题干中的值3

  • 3/(-2) = -1 ······ 1
  • -1/(-2) = 0 ······ -1

呃,好像哪里不对,虽然根据之前的特殊值 (-1)10 = (11)-2 ,可以推出 3/(-2) 商为 -1 余数为 1,所以 (3)10 = (111)-2,貌似也搞定了。

1.3 试一下特殊值-13

先在代码里运行一下 -13/(-2),得到商为6,余数为-1。等等,余数为-1是什么鬼,余数不应该是1或者0吗?再想想,应该得到的商为7,余数为1,这样就行了。于是:

  • -13/(-2) = 7 ······ 1
  • 7/(-2) = -3 ······ 1
  • -3/(-2) = 2 ······ 1
  • 2/(-2) = -1 ······ 0
  • -1/(-2) = 1 ······ 1
    所以,(-13)10 = (110111)-2
    验算一下,(-2)5+(-2)4+(-2)2+(-2)1+(-2)0 = -32+16+4-2+1 = -13 。没毛病!

结论,当被除数为负数,余数为-1时,计算所得的商应该加一,余数就变为正1

2 代码实现go和java

//go语言实现
func intToNegativeBinary(n int) { 
	if n == 0 { 
		fmt.Println(0)
		return
	}
	const BASE = -2
	var ans []byte
	for n != 1 { 
		if n > 0 { 
			ans = append(ans, byte('0'+n%BASE))
			n /= BASE
		} else { 
			yu := n % BASE
			if yu == -1 { 
				//余数为-1
				n = n/BASE + 1
				ans = append(ans, '0'+byte(1))
			} else { 
				ans = append(ans, '0'+byte(yu))
				n /= BASE
			}
		}
	}
	//把最后剩下的1加进去
	ans = append(ans, '0'+byte(1))
	
	length := len(ans)
	//反转
	for i := 0; i < length/2; i++ { 
		ans[i], ans[length-1-i] = ans[length-1-i], ans[i]
	}
	fmt.Println(string(ans))
}
//java代码实现
public static void intToNegativeBinary(int n){ 
        if (n == 0){ 
            System.out.println(0);
            return;
        }
        int BASE = -2;
        StringBuilder str = new StringBuilder();
        while (n != 1){ 
            if (n > 0){ 
                str.append(n%BASE);
                n/=BASE;
            } else { 
                int yu = n%BASE;
                if (yu == -1){ 
                    //余数为-1
                    n = n/BASE + 1;
                    str.append(1);
                } else { 
                    str.append(n%BASE);
                    n/=BASE;
                }
            }
        }
        //把最后剩下的1加进去
        str.append(1);
        str.reverse();
        System.out.println(str);
    }

java代码,也可以不用先append,再reverse,可以直接用 str.insert(0, 1); 实现向最前append。
自己测试了一下,大量数据时,如量级在105,两个时差接近20倍,所以先append再reverse 速度更快。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服