【C++语法】加减乘除模 与 类型的强制转换
文章目录
- 【C++语法】加减乘除模 与 类型的强制转换
- 1. 四则混合运算与取模运算符
- 1.1 加减乘运算
- 1.2 除与模运算
- 2. 类型的强制转换
【C++语法】加减乘除模 与 类型的强制转换
在 C/C++ 中也有加减乘除,还有一个模运算,但是它们有一些奇妙的组合来完成一些意想不到的操作。还有 C/C++ 中的类型强制转换
1. 四则混合运算与取模运算符
1.1 加减乘运算
加减乘非常好理解,就是左边一个数,右边一个数,可以相加、相减和相乘
a+b// a 与 b 相加a-b// a 与 b 相减a*b// a 与 b 相乘当然,你也可以在一个数字前面加一个-表示这个数的相反数
C++ 中乘除模的优先级比加减高,如果你想改变优先级,可以加上一对括号,就像这样a * b + c= a × b + c =a\times b+c=a×b+ca * (b / (c + d))= a × [ b ÷ ( c + d ) ] =a\times \left[b\div(c+d) \right]=a×[b÷(c+d)]a * (b * (c + d) * e)= a × [ b × ( c + d ) × e ] =a\times[b\times(c+d)\times e]=a×[b×(c+d)×e]
1.2 除与模运算
为什么会把加减乘与除模分开呢?在 C/C++ 中,除号运算符会根据运算符左右的类型是整型还是浮点型来进行不同的操作,而模的话又有一些限制条件
如果左右两边的数字或变量之间有一个是浮点型,那么就表示两数相除,最终的结果始终是浮点数类型;否则如果都是整型,就表示两个数字做带余除法,相除后的商。这个符号写作/
10/3// 结果返回 3 ,类型为 整型10.0/3// 返回结果3.333 ,类型为 浮点型我们会发现两个整数a , b a, ba,b相除,最终的结果等于⌊ a b ⌋ \lfloor \cfrac{a}{b} \rfloor⌊ba⌋,也就是两个整数相除后向下取整的结果,且不会进行类型转换
那么有了向下取整,又应该如何两个整数a , b a, ba,b相除以后向上取整的结果呢?
第一种方法是使用 C语言的math.h(C++ 的cmath)库中的函数ceil(x),向下取整floor(x),向零取整trunc(x),四舍五入round(x),但是这些函数都是对于小数使用的,虽然整数也可以,但是不保险也不安全,因为会进行浮点数与整数的类型转化,可能会导致精度丢失,从而计算错误
第二种方法就是列一个数学公式了。我们知道,向上取整会将这个小数向上拉,在结果为整数时不管。所以假如要求⌈ a b ⌉ { a ∈ N , b ∈ N } \lceil \cfrac{a}{b} \rceil \{ a\in\mathbb{N},b\in\mathbb{N}\}⌈ba⌉{a∈N,b∈N},那么这个数字的结果就等于⌊ a + b − 1 b ⌋ \lfloor \cfrac{a+b-1}{b} \rfloor⌊ba+b−1⌋
两数相除四舍五入保留到整数呢?我们知道四舍五入的规则是:假如保留整数,那么就看第一位小数⩾ 5 \geqslant5⩾5那么向上舍入,否则< 5 \lt5<5就向下舍入。所以一个数字如果+ 0.5 +0.5+0.5再向下舍入就可以得到四舍五入的结果,r o u n d ( a b ) = ⌊ a b + 0.5 ⌋ round(\cfrac{a}{b})=\lfloor \cfrac{a}{b} + 0.5 \rfloorround(ba)=⌊ba+0.5⌋(r o u n d ( x ) round(x)round(x)表示 对x xx四舍五入)。但是,如果+ 0.5 +0.5+0.5也会强制类型转换,所以我们可以让向下取整中× 2 \times2×2,里面算完后再÷ 2 \div2÷2得:
r o u n d ( a b ) = ⌊ 2 ( a b + 0.5 ) 2 ⌋ r o u n d ( a b ) = ⌊ 2 a b + 1 2 ⌋ round(\cfrac{a}{b})=\left\lfloor \cfrac{2(\cfrac{a}{b} + 0.5)}{2} \right\rfloor \\ round(\cfrac{a}{b})=\left\lfloor \cfrac{\cfrac{2a}{b} + 1}{2} \right\rfloor \\round(ba)=22(ba+0.5)round(ba)=2b2a+1
| 要求 | 代码 |
|---|---|
| 求出:⌊ a b ⌋ { a ∈ N , b ∈ N } \left\lfloor \cfrac{a}{b} \right\rfloor \left\{ a \in \mathbb{N}, b \in \mathbb{N} \right\}⌊ba⌋{a∈N,b∈N} | a / b |
| 求出:⌈ a b ⌉ { a ∈ N , b ∈ N } \left\lceil \cfrac{a}{b} \right\rceil \left\{ a \in \mathbb{N}, b \in \mathbb{N} \right\}⌈ba⌉{a∈N,b∈N} | (a + b - 1) / b |
| 求出:r o u n d ( a b ) { a ∈ N , b ∈ N } round\left(\cfrac{a}{b}\right) \left\{ a \in \mathbb{N}, b \in \mathbb{N} \right\}round(ba){a∈N,b∈N} | (2 * a / b + 1) / 2 |
那么模运算又是什么呢?在数学公式中表示为a m o d b a \bmod bamodb,在C++最终表示为%,表示两个整数作带余除法,最终的余数是多少
17%5// 结果为 221%3// 结果为 0也就是a m o d b = a − ⌊ a b ⌋ { a ∈ [ 0.. ∞ ) , b ∈ [ 0.. ∞ ) } a \bmod b=a -\left\lfloor \cfrac{a}{b} \right\rfloor\left\{ a\in[0..\infin),b\in[0..\infin) \right\}amodb=a−⌊ba⌋{a∈[0..∞),b∈[0..∞)}
那么假如有一个或两个数是负数呢?例如-17 % 5等于多少,17 % -5等于多少,-17 % -5又等于多少?在 C++ 中,左数的正负符号就是右数的正负符号,而右边取绝对值,正负不影响结果
17%5// 等于 2-17%5// 等于 -217%-5// 等于 2-17%-5// 等于 -2但是,在 Python 中,模后的结果始终是正数,这个叫做真模运算。想要让 C++ 也有这个效果,那么就需要这么写:(a % m + m) % m(a是被模数,m是模数)
在 C++ 中不允许使用%让两个之中有一个浮点数的式子运算,想要运算需要使用math.h库中的fmod(a, m)函数来对小数取模(a是被模数,m是模数)
2. 类型的强制转换
在 C语言中提供了一种转换方法:强制类型转换。强制类型转换的语法十分简单,就是将这个变量/表达式用括号框起来,再在前面加上转换后的类型也加上括号,也就是(类型)(表达式)
表达式:可以是一串算式,可以是一串代码
对于整型(int)、长整型(long)、双长整型(long long)和浮点型(float/double/long double)类型的数字之间的转换而言,整型后面什么都不加,长整型后面加一个l,双长整型后面加上ll,浮点型后面加一个.就够(可能看起来不靠谱,但是真的能运行),不过含有.的都是浮点型
在 C++ 中提供了两种转换方法:static_cast<类型>(表达式)、dynamic_cast<类型>(表达式),第一种在程序运行前自动转换,第二种在程序运行中转换的,依赖 RTTI(运行时类型识别)。这样安全性更高,但在信奥赛中有些小题大做,不如强制转换;编写 C++ 小程序时就刚好(一共有四种,但剩下两种转换并不安全:const_cast<类型>(表达式)与reinterpret_cast<类型>(表达式))
#include<iostream>usingnamespacestd;intmain(){cout<<20./6.<<endl;// 输出 3.33333cout<<1234567890ll+11451410086ll+32767987654321ll<<endl;// 输出 32780673632297}