0%

0-3 四則運算

四則運算

在C++裡,四則運算大多就跟平常一樣。也遵從著先乘除後加減、括號先算……等等正常的運算規則。

在進行很大的數字相加/相乘時務必注意,若於運算中之任何時刻超過int可表示的範圍,即使最終答案在int範圍,也會導致overflow而使答案錯誤

overflow的說明

1
2
int a = 5, b = 3;
cout << a+b << ' ' << a-b << ' ' << a*b << '\n';

結果:

1
8 2 15

除法

1
2
int a = 5, b = 3;
cout << a/b << '\n';

結果:

1
1

會有這樣的結果是因為,5是一個整數,3也是一個整數,整數之間的運算,結果在C++裡只會是整數。

因此,小數點以後的部分被捨棄了。

除以 0

在除以 0 時,程式會產生執行期間錯誤(Runtime Error),在 Online Judge 上顯示為 RE / Runtime Error / Segmentation fault。請務必注意此情形,並且預先處理掉除數可能為 0 的情況。

如何讓整數之間的運算結果產生小數

你可以在運算時預先乘上 1.0 ,這樣,在進行運算時,數字是以浮點數的方式進行運算,最終結果也自然就是浮點數了。

1
2
int a = 5, b = 3;
cout << 1.0*a/b << '\n';

結果:

1
1.66667

控制小數點以下的輸出位數

從上面的例子,我們可以發現,答案只輸出到小數點後第五位。

若要輸出到小數點後第十位,該怎麼做呢?

1
2
3
4
5
6
7
8
9
10
#include<iostream>
#include<iomanip>
//#include<bits/stdc++.h> // 萬用標頭檔
using namespace std;

int main(){
int a = 5, b = 3;
cout << fixed << setprecision(10) << 1.0*a/b << '\n';
}

結果:

1
1.6666666667

其中,fixed表示的,是小數點以下的意思,因此,若沒有fixed,setprecision(10)代表的,其實是總共輸出十位數字。

fixed與setprecision在iomanip標頭檔中,使用時必須先

1
#include<iomanip>

如使用萬用標頭檔bits/stdc++.h則不須理會。

設定一次輸出位數後,下一次便不需要重新設定,例如:

1
2
3
int a = 5, b = 3;
cout << fixed << setprecision(10) << 1.0*a/b << '\n';
cout << 3.0*a*b/1.24*0.445 << '\n';

結果為:

1
2
1.6666666667
16.1491935484

模運算

若我們要取得 a 除以 b 的餘數,可以這樣寫:

1
2
3
int a, b;
cin>> a >> b;
cout<< a - a/b*b << '\n';

因 $a,b$ 都是整數,因此 $a/b$ 僅會保留整數部分,根據除法原理,$a / b = c … d$ 可改寫為 $a = b * c + d$,其中 $0 \le d < b$。因此,$c$ 就是 $a/b$ 的整數部分,將 $a$ 減去 $b*c$ 後,就得到餘數 $d$ 了!

其實,在C++裡,有個幫你寫好的餘數功能:

1
2
3
int a, b;
cin >> a >> b;
cout << a % b << '\n';

% 的優先次序與乘除法相同,因此,若要取 a+b 除以 c 的餘數,必須這樣寫:

1
2
3
int a, b, c;
cin >> a >> b >> c;
cout << (a + b) % c << '\n';

運算後指派

1
2
3
4
5
int a = 5, b = 4, c = 0;
a = a + 1; // 計算 a+1 後 指派給 a,現在 a 是 6
b = a - 1; // 計算 a-1 後 指派給 b,現在 b 是 5
c = a * b; // 計算 a*b 後 指派給c,現在 c 是 30
cout<<a<<b<<c<<'\n';

C++ 中,針對 $a = a + 5$ 之類的操作,有著更簡潔的寫法:

1
2
3
4
a += 5; // a = a + 5
b -= 2; // b = b - 2
c *= 3; // c = c * 3
d /= 45; // d = d / 45

針對 $a = a + 1$ 之類的操作,還有更簡單的寫法:

1
2
a++; // a += 1
b--; // b -= 1

練習

TOJ 93

TOJ 98

TOJ 522

AC Code (強烈建議自行寫完後再看)

1
2
3
4
5
6
7
8
9
10
// TOJ 93
#include<iostream>
using namespace std;

int main() {
int a,b,c;
cin>>a>>b>>c;
int s=(a+b)*c/2; // why (a+b)/2*c is wrong???
cout<<s<<"\n";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// TOJ 98
#include<iostream>
using namespace std;

int main() {
long long a,b,c,d,e,f;
// 如果用int,會發生什麼?
a=299792458;
b=a*60;
c=b*60;
d=c*24;
e=d*7;
f=d*365;

cout <<"1 Light-second(LS) is "<<a<<" metres.\n";
cout <<"1 Light-minute(LM) is "<<b<<" metres.\n";
cout <<"1 Light-hour(LH) is "<<c<<" metres.\n";
cout <<"1 Light-day(LD) is "<<d<<" metres.\n";
cout <<"1 Light-week(LW) is "<<e<<" metres.\n";
cout <<"1 Light-year(LY) is "<<f<<" metres.\n";
}
1
2
3
4
5
6
7
8
9
// TOJ 522
#include <iostream>
using namespace std;

int main() {
int x;
cin>>x;
cout<<x*x%10<<'\n';
}