C++函数篇补充 - 库函数

C++函数篇补充 - 库函数

C语言提供了很多编写好的函数,供用户在编程时使用,这些函数被称为库函数,当然C++语言也可以使用。

1、与字符相关的函数

下面是一些关于字符使用的函数:

函数名 格式 功能说明 实例
输入单个字符 getchar() 输入当个字符 c=getchar();
输出单个字符 putchar() 输出当个字符 c='a'
putchar( c );
判断是否为小写字母函数 islower( x ) 判断x是否为小写字母 islower('a')==true
判断是否为大写字母函数 isupper( x ) 判断x是否为大写字母 isupper('A') == true
isupper('1') == 0
判断是否为数字函数 isdigit( x ) 判断x是否为数字 isdigit('9') == 1
isdigit(‘A’) ==0
判断是否为字母函数 isalpha( x ) 判断x是否为字母 isalpha('a') == 2
isalpha('A') == 1
isalpha('9')==0
ASCII码转字符函数 char( ) 将ASCII码转成字符 char(97) == 'a'
char(65) == 'A'
char(48) == '0'
字符转ASCII码函数 int( c ) 经字符转成ASCII码 int('a')==97

字符类型判断

#include<bits/stdc++.h>
using namespace std;
int main(){
	char a;
	a = getchar();
	if (isupper(a))cout<<"upper";
	else if (islower(a))cout<<"lower";
	else if (isdigit(a))cout<<"digit";
	else cout<<"other";
	return 0;
}

大小写字母转换

#include<bits/stdc++.h>
using namespace std;
int main(){
	char c;
	cin>>c;
	if (isupper(c)){
		cout<<c+32; // char(c+32)
	}else{
		cout<<char(c-32);
	}
	return 0;
}

2、与整型相关的数学库函数

在C++中系统给出了很多的处理整型的函数。

函数名 格式 功能说明 例子
绝对值函数 abs( x ) 求一个数x的绝对值 abs(-5)
最大值 max(x,y) 求连个数的最大值,可以是整型、字符型、实型 max(1,2) == 2
max('a','z')== a
max(3.14,2.72)==3.14
最小值 min(x,y) 求两个数的最小值 min(1,2) == 1
min('a','z')== z
min(3.14,2.72)==2.72
交换 swap(x,y) 交换两个对象的位置 x=10,y=20
swap(x,y)
x == 20 ,y ==10
取整数部分 int(x) 取实数x的整数部分 int(1.2)== 1
int(1.9) == 1
int(-1.9)== -1
int(-1.2)== -1
指数函数 pow(x,y) 计算x**y,结果为双精度实数 pow(2,3)=8
随机数函数 rand() 产生0到rand-max之间的随机整数

乘方计算

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,a;
	cin>>a>>n;
	cout<<int(pow(a,n));
	return 0;
}

绝对值排序

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b,c;
    cin>>a>>b>>c;
    if (abs(a)> abs(b) || abs(a) == abs(b) && a>b) swap(a,b);
    if (abs(b)> abs(c) || abs(b) == abs(c) && b>c) swap(b,c);
    if (abs(a)> abs(b) || abs(a) == abs(b) && a>b) swap(a,b);
    cout<<a<<' '<<b<<' '<<c;
    return 0;
}

第一个数a个第二个数b,发生交换的条件有两个:a的绝对值要比b的绝对值大abs(a)>abs(b)或者当两个数的绝对值一样时,abs(a) == abs(b)数大的在前面a>b。然后第二个数b和第三个数c比较,是否要交换的原则和上面一样,最后再将第一个数和第二个数比较交换。

最小数和最大数

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, x, maxx, minx;
    cin >> n;
    cin >> maxx;
    minx = maxx;
    for (int i = 2; i <= n; i++) {
        cin >> x;
        maxx = max(x, maxx);
        minx = min(x, minx);
    }
    cout << minx << ' ' << maxx;
    return 0;
}

我们先规定第一个数是最大的值也是最小值,并赋值给maxx和minx,循环部分表示如果x要比maxx大,那么maxx被替换成x,如果x要比minx小,那么minx备胎换成x;最后maxx和minx就是我们要的最大值与最小值。

3、与实型相关的数学库函数

在计算机中小数点一般有两种表示法,一种是小数点固定在某一个位置的顶点表示法;另外一种是小数点的位置可以任意移动的浮点表示法。相应于这两种表示的计算机分别称为定点计算机和浮点计算机。

1)定点表示法

机器中所有数的小数点位置是固定不变的,因而小数点就不必使用记号表示出来。实际上,小数点可固定在任意一个位置上。

2)浮点表示法

在数的顶点表示法中,由于数的表示范围较窄常常不能满足各种数值问题的需要。为了扩大数的表示范围,方便用户使用,有些计算机常采用浮点表示法。表示一个浮点数,要用两个部分:尾数和阶码。

尾数用以表示数的有效数值;阶码用以表示小数点在该数中的什么位置。

计算机多数情况下采用浮点数表述数值,它与科学计数法相似,吧一个二进制数通过移动小数点位置表示成阶码和尾数两部分:

$$
N = 2^E × S
$$

E:N的阶码(Expoent),是有符号的整数,用于存储科学计数法中的指数数据,并且采用位移存储。

S:n的尾数(Mantissa),是数值的有效数字部分,一般规定取二进制顶点纯小数形式。

$1011101B = 2^{+6} * 1.011101$

$101.1101B = 2^{+2} * 1.011101$

$0.01011101B = 2^{-2} * 1.011101$

一个float类型的变量,占4个字节(每个字节8位,共32位),符号位占1位,阶码占8位,尾数占23位,存储方式如下所示:

image

一个float类型小数点用科学计数法表示的时候,小数点前面是1,其余各位作为尾数部分,这样省略了一个1,提高了精度。阶码采用以为存储,存储的数据为阶码的原数据+127.例如:8.25,用二进制的科学计数法表示为:$1.0001 * 2^3$

1、科学计数法怎么表示

科学计数法就是用幂的方式来表示。科学记数法是一种记数的方法。把一个数表示成a与10的n次幂相乘的形式 (1 ≤ |a| <10,n为整数),这种记数法叫做科学记数法。

科学记数法是一种记数的方法。把一个数表示成a与10的n次幂相乘的形式(1 ≤|a|<10,n为整数),这种记数法叫做科学记数法。例如: 19971400000000=1.99714X10^13。计算器或电脑表达10的幂是一般是用E或e,也就是1.99714E13=19971400000000。

科学记数法的形式是由两个数的乘积组成的。表示为aX10^b (aEb),其中一个因数为a(1≤|a|<10),另一个因数为$10^n$。

2、科学计数法的运算规则

1、数字部分:保留一份整数,其余均为小数;
2、指数部分:对于大于10的数,其指数为整数位数-1,例如: $13=1.3E1$ ,13有2位整数,减1,故指数部分为1;
3、指数部分:对于小于1的数,第一个不是0的数前面。

3、科学计数法精确到哪一位怎么看

科学计数法的精确度以a的最后一个数在原数中的数位为准。如: 13600,精确到十位,记作: 1.360X10*4;13200,精确到百位,记作:1.32X10^4; 322000,精确到千位,记作: 3.22X10^5。

按照上面的存储方式,符号位为:0,(0表示正数,1表示负数),指数位为3+127=130,

https://zhuanlan.zhihu.com/p/503336736

https://baike.baidu.com/item/移码/10165919?fr=ge_ala

Double类型的数据和float类型大同小异,阶码采用移位存储时,存储数据为阶码的原数+1023,存储方式如下图:

image

计算机在存储有些小数时,存的是近似值,而非精确值。比如,$0.525=(0.101)_2$ 可以精确表示,$0.1 = (0.00011001100...)_2$,其中1100是循环节。由于float或Double的存储位数有限,所以只能存近似值了。

下面罗列了一些针对整型可以使用的库函数。

函数名 格式 功能说明 例子
向下取整 floor(x) 求不大于实数x的最大整数 floor(3.14)=3
向上取整 ceil(x) 求不小于实数x的最小整数 ceil(3.14)=4
四舍五入 round(x) 实数x进行四舍五入 round(5.5)=6
取整 trunc(x) 去除数字的小数部分,功能和函数INT类似 trunc(5.5)=5
自然对数函数 log(x) 求实数x的自然数对数 log(1)=0
平方根值函数 sqrt() 求实数x的平方根 sqrt(25)=5
取绝对值 fabs(x) 取实数x的绝对值 fabs(-1.2)=1.2
#include<iostream>
#include<math.h> 
using namespace std;
int main(){
	float a = 3.14;
	cout<<"向下取整:"<<floor(a)<<endl;
	cout<<"向上取整:"<<ceil(a)<<endl;
	cout<<"四舍五入:"<<round(a)<<endl;
	a = -3.14;
	cout<<"取绝对值"<<fabs(a)<<endl; 
	return 0;
} 

4、整数的进制转换

电子计算机中的所有信息都是以二进制的形式存储、处理和传输的,而在日常生活中还会使用其他进制数,他们之间可以进行相互转换。

进制计数制的基本概念

将数字符号按序排列成数位,并遵照某种由低位到高位的进位方式计数表示数值的方式,称作进位计数制。

位数(从右到左):在十进制中我们有个位,十位,百位,千位,万位等;
但在二进制中我们以数字,第0位,第1位,第2位,第3位,第四位等。

1、十进制

十进制(Decimal System),缩写Dec或D。十进制计数制由0、1、2、3、4、5、6、7、8、9共10个数符号组成。相同数字符号不同的数位上表示不同的数值,每个数位计满十就向高位进一,即“逢十进一”。

2、八进制

八进制(Octal),缩写Oct或O。八进制计数制由0、1、2、3、4、5、6、7共八个数字符号组成。相同数字符号在不同的数位上表示不同的数值,每个数位计满八就向高位进一,即“逢八进一”。

3、二进制

二进制(Binary),缩写Bin或B。二进制计数制有0和1共两个数字符号组成。相同数字符号在不同的数位上表示不同的数值,每个数位计满二就向高位进一,即“逢二进一”。

4、十六进制

十六进制(Hexadecimal),缩写Hex或H。十六进制由0、1、2、3、4、5、6、7、8、9、a、b、c、d、e、f共十六个符号组成,相同数字符号在不同的数位上表示不同数值,每个数位计满十六就向高位进一,即“逢十六进一”。

5、其他进制

在日常生活和日常工作中还会使用其他进制数。如:十二进制数,百进制数和千进制数等。无论那种进制数,表示的方法都是类似的。如:是二进制数由0、1、2、3、4、5、6、7、8、9、a、b共十二个符号组成,“逢十二进一”。不同的使用a、b分别表示10、11这两个数字符号

6、基数与权

某进制计数制允许选用的基本数字符号的个数成为基数。一般而言,J进制数的基数为J,可供选用的基本数字符号有J个,分别为0到J-1,每个数为计满J就向高位进一,即“逢J进一”。

某进制计数制中各位数字符号所表示的数值表示该数字符号值乘以一个与数字符号有关的常数,该常数成为“位权”(简称“权”)。位权的大小是以基数为底,数字符号所处的位置的序号为指数的整数次幂。

十进制数允许使用十个基本数字符号,所以基数为10,每位数字符号代表的尾数的大小是以10为底,数字符号所处位置的需要为指数的整数次幂。位置从0开始。

十进制数的百位,十位,各位和十分位的权分别为:$102$,$101$,$100$,$10$。故$(555.5){10}$可表示成$(555.5) = 510^2 + 510^1 + 510^0 + 510{-1}$。J进制数相邻两位数相差J倍,若小数点向左移n位,则整个数值就缩小$Jn$。反之小数点向右移动n位,数值就放大$J^n$。

如下表所示,给出了任意进制数($K^2$ $K^1$ $K^0$ $K^{-1}$ $K^{-2}$),当J分别为:2,8,10,16时各位权值对照。

$k^2$ $k^1$ $k^0$ 小数点 $k^{-1}$ $k^{-2}$
J = 2 $2^2 = 4$ $2^1 = 2$ $2^0 = 1$ $2^{-1} = 0.5$ $2^{-2} = 0.25$
J = 8 $8^2 = 64$ $8^1 = 8$ $8^0 = 1$ $8^{-1} = 0.125$ $8^{-2} = 0.015625$
J = 10 $10^2 = 100$ $10^1 = 10$ $10^0 = 1$ $10^{-1} = 0.1$ $10^{-2} = 0.01$
J = 16 $16^2 = 256$ $16^1 = 16$ $16^0 = 1$ $16^{-1} = 0.0625$ $16^{-2} = 0.00390625$

进制之间的转换

计算机内部使用的数字符号只有“0”和“1”两个数,也就是说计算机内部使用的是二进制数所有的数值数据和非数值数据,都是有“0”和“1”这两个数字符号加以组合而成的,我们称之为“二进制代码”。

计算机只用二进制的两个数码“0”和“1”来实现算术和逻辑运算,而人们仍然用十进制的形式向计算机中输入原始数据,并让计算机也用十进制形式显示和打印运算结果。所以必须有一种自动转换方法,即让数据输入计算机后,将十进制转成对应二进制数,并在处理完毕后,再自动将二进制结果转换为十进制数。

为了表达方便起见,常在数字后面加一缩写字母后缀作为不同进制数的标识。各种进制数的后缀字母分别为:

字母后缀 标识进制
B 二进制数
O 八进制数
D 十进制数
H 十六进制数

对于十进制数通常不加后缀,也即十进制数后的D可以省略。

1、二进制与十进制的转换

二进制转十进制

方法:“按权展开求和”

$(1011.01)2 = (1×2^3 + 0×2^2 + 1×2^1 + 1×2^0 + 0×2^{-1} + 1×2^{-2})$

$ = (8+0+2+1+0+0.25)_{10}$

$ = (11.25)_{10}$

十进制转二进制

十进制整数转二进制数:“除以2取余,逆序输出”

例:$(89)_{10} = (1011001)_2$

image

十进制小数转二进制数:“乘以2取整,顺序输出”

例:$(0.625)_10 = (0.101)_2$

image

2、八进制与二进制的转换

例:将八进制的37.416转换成二进制数:

根据每位数字对应的二进制合在一起就可以。

image

即$(37.413)_8 = (11111.10000111)_2$

还可以将八进制数转成十进制,再转成二进制

把一个八进制转成十进制采用方法:把这个八进制的最后一位乘上 $8^0$ ,倒数第二位乘上 $8^1$,...,一直到最高位上 $8^n$ ,然后将各项乘积相加的结果就他的十进制表达式。

image

二进制分成两部分整数部分与小数部分

$(31)_{10} = (11111)_2$

image

$(0.52734375)_{10} = (10000111)_2$

image

将二进制的10110.0011转换成八进制:

三位为一组,三位全是1(111)正好为7。

image

即:$(10110.0011)_2 = (26.14)_8$

还可以转换为十进制,然后再转换为八进制。

$(10110.0011)2 = (22.1875)$

image

$(22.1875)_{10} = (26.14)_8$

整数部分:

image

小数部分:

image

3、十六进制与二进制的转换

例:将十六进制数 5DF.9 转换成二进制。

四位的二进制全是1 即为15,也就是十六进制最大值

image

即:$(5DF.9)_{16} = (10111011111.1001)_2$

也可以采用十六进制转十进制,十进制转二进制;

把一个十六进制转换成十进制采用方法:把这个十六进制的最后一位乘上$160$,倒数第二位乘上$161$,...,一直到最高位乘上$16^n$ ,然后将各位乘积相加的结果就是他的十进制表达式

十六进制转十进制,就是以16为基数。

image

image

image

将二进制数 1100001.111 转换成十六进制

从后向前四位为一组,不够用0补位。

image

即:$(1100001.111)2 = (61.E)$

也可以通过十进制来进行转换

image

image

image

函数转换方式

八进制转十进制

#include<iostream>
using namespace std;
int main(){
	int x;
	scanf("%o",&x);
	printf("%d",x);
	return 0;
}

使用格式化输入输出,通过scanf函数以八进制的格式%o 输入,通过 printf 函数以十进制的格式%d 输出。注意scanf 函数x变量前面的“&”为取地址符。

ip地址的转换

192.168.1.1 需要11位保存,如果使用十六进制,便只需要八位了。将十进制转成十六进制。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a,b,c,d;
	scanf("%d.%d.%d.%d",&a,&b,&c,&d);
	printf("%02x%02x%02x%02x",a,b,c,d);
	return 0;
} 

将十进制数通过“除2取余,逆序输出”方式,转换成二进制。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int x;
	cin>>x;
	if (x == 0){
		cout<<x;
	}
	while(x>0){
		cout<<x%2;
		x/=2;
	}
	return 0;
} 

注意这里是从地位到高位输出,并不是二进制的数。

5、以二进制角度看整数

1、整数的原码、补码和反码表示

在计算机系统中,数值一律用补码来表示和存储。原因在于:补码表示统一了符号位和数值位,是的符号位可以和数值为一起直接参与运算;同时,加法和减法也可以统一处理,即可以将减法运算转化为补码的加法运算来实现,克服了原码加减法运算繁杂的弊端,有效简化了运算器的设计。

(1)原码表示

原码表示法是一种简单的机器数表示法,即符号和数值表示法,设x为真值,$[X]_原$ 为机器数表示。

在二进制前面有一个符号位,正为0,负位1

例:设 x = 1100110,则 $[X]_原$ = 01101110

x = -1100111 , 则 $[X]_原$ = 11100111

(2)反码表示法

正数的反码就是真值本身;负数的反码,只需要对符号位以外各位按位“求反”(0变1,1变0)即可。

例:X = 1100110,则$[X]_反$ = 01100110

X = -1100111,则$[X]_反$ = 10011000

(3)补码表示

负数用补码表示时,可以把减法转化成加法,正数的补码就是真值本身;负数的补码是符号位为1,数值各位取反(0变成1/1变成0),最低位加1。

例:X = 1100110,则$[X]_补$ = 01100110

X = -1100111,则$[X]_补$ = 10011001

从上面关于原码、反码、补码的定义可知:一个正数的原码、反码、补码的表示形式相同,符号位为0,数值位是真值本身;一个负数的原码、反码、补码的符号为都是1,数值位原码是真值本身,反码是各位取反,补码是各位取反,最低位加1.真值0的原码和反码表示不唯一,而补码表示是惟一的。

即:$[+0]_原$ = 000···0,$[-0]_原$ = 100···0

$[+0]_反$ = 000···0,$[-0]_原$ = 111···1

$[+0]_补$ = $[-0]_原$ = 000···0

注:不同编码表示的整数范围(N位二进制):

原码:0 ~ $-2^n-1$ (无符号)

$-2^{n-1}-1$ ~ $-2^{n-1}-1$(有符号)

反码:-2^{n-1}-1 ~ -2^{n-1}-1(不存在无符号的情况)

补码:$-2^{n-1}$ ~ $-2^{n-1}-1$(不存在无符号的情况)

计算机中的有符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同 。在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。

大家很明显看出,补码表示的范围最大。现以八位二进制为例说明如下:

原码:00000000 ~ 11111111 即 0-255(无符号)

11111111 ~ 01111111 即 -127 ~ +127 (有符号)

反码:100000000 ~ 01111111 ,即-127 ~ +127(因为10000000的值为-127,11111111的值为-0)

补码:10000000 ~ 01111111,即 -128 ~ +127 (因为10000000的值为-128,11111111的值为-1)

如果没说具体编码形式,则计算机中N位二进制无符号的范围是0 ~ $-2^n-1$ ;有符号的范围是 $-2^{n-1}$ ~ $-2^{n-1}-1$ 。因此一个int类型的变量,占4个字节,表示范围为 $-2^{32}$ ~ $-2^{31}-1$ ,即2147483647 ~ -2147483648 ,如果超出这个范围,就会产生溢出现象。

2、bitset操作

Bitset 是C++语言的一个类库,用来方便地管理一系列的bit位而用程序员自己来写代码。

bitset除了可以访问指定下标的bit位以外,还可以把它们作为一个正数来进行某些统计。

(1) 声明

可以如下声明一个该类型变量

bitset<N>varm (M)
// 其中varm为变量名
// N表示改类型在内存中占的位数,是二进制。
// M表示变量varm的初始值。

(2) 操作

函数名称 作用
any() 为了测试bitset对象是否含有被设置为1的位,我们可以使用any()操作
none() 如果bitset对象的所有位都被设置为0,则none()操作返回true
count() 返回被设置为1的位的个数
set() 用set()操作或者下标操作符来设置某个单独的位
test() 测试某个单独的位是否为1
reset() 用reset()操作或下标操作符来将某个单独的位设置为0
flip() 翻转整个bitset对象或一个独立的位

输出二进制补码


#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	bitset<8> b(n);
	cout<<b;
	return 0;
} 

统计1的个数

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	bitset<32> bs(n);
	cout<<bs.count();
	return 0;
} 

6、位运算与builtin内建函数

1、位运算

C++语言提供了6中位运算符

运算符 含义 说明 例子
& 按位与 把参与运算的两个数对应的二进制相与,只有对应的二进制均为1时,结果的对应为才为1,否则为0 9&5,9(00001001,5(00000101)结果为00000001,输出结果为1
| 按位或 把参与运算的两个数对应的二进制位相或,也就是只要对应的两个二进制位有一个为1时,其结果就位1。 9|5相当于00001001|00000101,运算结果是00001101,其结果是13。
^ 按位异或 把参与运算的两个数对应的二进制位想异或,当对应的二进制位上的数据字不相同时,结果对应为1时,否则为0。 11=0,10=1,00=0,01=1,95相当于0000100100000101,运算结果为00001100,输出的结果是12
~ 取反 把运算数的各个二进制位按位求反。 ~9 相当于~(00001001),运算结果为1110110
<< 左移 把“<<”左边的运算数的各二进制位向左移若干位,“<<”右边的数是指定移动的尾数,高位丢弃,低位补0。 a<<4指把a的各二进制位向左移动4位,如a=00000011(十进制为3),左移4位后为00110000(十进制48)
>> 右移 把“>>”左边的运算数的各二进制位全部右移若干位,“>>”右边的数是指定移动的位数 设a=15,a>>2表示把00001111右移为00000011(十进制为3)。

对于有符号数,在右移时,符号位将随同移动。当从操作数为正数时,最高位为0,而为负数时,最高位为1.最高位是补0或补1取决于编译系统的规定。

2、builtin 内建函数

GCC提供了一系列的builtin函数,可以实现一些简单快捷的功能来方便程序编写。

用法 说明
__builtin_ffs(x) 返回x中最后一个为1的位是从后向前的第几位,如__builtin_ffs(0x789) = 1.__builtin_ffs(0x78c)=3。于是,__builtin_ffs(x) - 1 就是x中最后一个为1的位的位置
__builtin_popcount(x) x中1的个数
__builtin_ctz(x) x末尾0的个数,x=0时结果未定义
__builtin_clz(x) x前导0的个数,x=0时结果未定义
__builtin_parity(x) x中1的奇偶性

注意:函数参数x应该是unsigned int,unsigned long以及unsigned long long。或者被强制转成这三种类型。

高低位交换

给出一个小于 232的正整数。这个数可以用一个 32 位的二进制数表示(不足 32 位用 0 补足)。我们称这个二进制数的前 16 位为“高位”,后 16

位为“低位”。将它的高低位交换,我们可以得到一个新的数。试问这个新的数是多少(用十进制表示)。

例如,数 1314520用二进制表示为0000 0000 0001 0100 0000 1110 1101 1000(添加了 11 个前导 0 补足为 32 位),其中前 16 位为高位,即0000 0000 0001 0100;后 16 位为低位,即0000 1110 1101 1000。将它的高低位进行交换,我们得到了一个新的二进制数 0000 1110 1101 1000 0000 0000 0001 0100。它即是十进制的 249036820。

#include<bits/stdc++.h>
using namespace std;
int main(){
	unsigned int n,num1,num2;
	cin>>n;
	num1 = (n<<16);
	num2 = (n>>16);
	cout<<(num1|num2);
	return 0;
} 

寻找最低位

给你一个正整数A(1≤A≤2.1×109),输出A的最低数。

例如,给你 A=26,我们可以将A化成二进制为 11010 ,则A 的最低数是 10,输出 10 的十进制为 2。

再例如,给你 A=88,我们可以将A化成二进制为 1011000,则A的最低数是1000,输出为8。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	while(cin>>n){
		if(n==0)break;
		cout<<(n&(-n))<<endl;
	}
	return 0;
} 

计算机里数值一律用补码来表示和存储的。整数的补码是原码,负数的补码是各位取反最低位加1,所以两者相与正好计算出最低数。

posted @ 2023-12-22 16:28  WNAG_zw  阅读(149)  评论(0)    收藏  举报