C++程序设计教程(钱能)第四章习题

1. 写出数学表达式所对应的C++表达式

(1) sqrt(pow(sin(x),2.5))
(2) (ax+(a+x)/(4a))/2
(3) (pow(c,(pow(x,2))))/(sqrt(2*x))

2. 写出下列表达式的值

//(1)
	int  e = 1, f = 4, g = 2;
	double m = 10.5, n = 4.0, k;
	k = (e + f)/g + sqrt(n)*1.2/g + m;
	cout << "(e + f)/g = " << (e + f) / g << "\n";//2
	cout << "sqrt(n)*1.2/g = " << sqrt(n)*1.2 / g << "\n";//1.2
	cout << "k = " << k << "\n";//13.7

//(2)
	double x = 2.5, y = 4.7;
	int a = 7;
	double k = x + a % 3 * (int)(x + y) % 2 / 4;
	cout << "a % 3 = " << a % 3 << "\n";//1
	cout << "(int)(x + y) % 2 = " << (int)(x + y) % 2 << "\n";//1
	cout << "a % 3 * (int)(x + y) % 2 / 4 = " << a % 3 * (int)(x + y) % 2 / 4 << "\n";//0
	cout << "k = " << k << "\n";//2.5
	/*运行结果:
		 a % 3 = 1
		 (int)(x + y) % 2 = 1
		 a % 3 * (int)(x + y) % 2 / 4 = 0
		 k = 2.5
	 */	

//(3)
	int a = 2, b = 5;
	a++;
	b++;
	cout << "a = " << a << "\n;";//3
	cout << "b = " << b << "\n";//6
	cout << "a+b = " << a + b << "\n";//9


3. 编程求值,注意不要让中间结果溢出

//求阶乘
double fun(int n) {
	double sum = 1;
	for (int i = 1; i <= n; i++) {
		sum *= i;
	}
	return sum;
}
void main() {
	cout << "fun(13)*fun(5) = " << fun(13)*fun(5) << endl;
	cout << "The result is " << fun(18)/(fun(13)*fun(5)) << "\n";	
	/*运行结果:
		fun(13)*fun(5) = 7.47242e+11
		The result is 8568
	*/
	//说明:13!*5! = 747 242 496 000 ,故中间结果没有溢出
}

4. 找出指定文件中,全部积为16!的数对

// abc.txt
112233 445566
8717829120000 2.4
16000000 1307674.368
10000  2092278988.8
1234567 890123
//实现代码
#include<iostream>
#include<sstream>
#include<fstream>
#include<cmath>
using namespace std;

double fun(int n) {
	double sum = 1;
	for (int i = 1; i <= n; i++) {
		sum *= i;
	}
	return sum;
 }
 
void main() {
	double temp = fun(16);
	ifstream in("abc.txt");
	for (string s; getline(in, s); ) {
		double multiply = 1;
		double a;
		for (istringstream sin(s); sin >> a; ) {
			multiply *= a;
		}
		if (abs(temp - multiply) < 1e-5)
			cout << s << "\n";
	}
}
//运行结果:
8717829120000 2.4
16000000 1307674.368
10000  2092278988.8

5. 编程输出long double型数12345.67891023456的二进制位码

//位操作是整数特有的操作,long double不能直接使用位操作,
//故把long double的8个字节拆解成两个4字节。
long double x = 12345.67891023456;//long double有8个字节
cout << sizeof(x) << "\n";
int* ph = reinterpret_cast<int*>(&x); //高四位地址
int ah = *ph;
int* pl = reinterpret_cast<int*>((&x) + 4);//低四位地址
int al = *pl;
for (int i = 31; i >= 0; i--) { //分别进行位操作处理
	if ((i + 1) % 8 == 0)
		cout << " ";
	cout << (*ph >> i & 1);
}
cout <<" ";
for (int i = 31; i >= 0; i--) {
	if ((i + 1) % 8 == 0)
		cout << " ";
	cout << (*pl >> i & 1);
}
cout << endl;
//运行结果1:11100110 10000111 11010011 00101101  00000000 11011101 11100001 01100000
//运行结果2:11100110 10000111 11010011 00101101  00000001 01001110 11110110 11010000
//运行结果3:11100110 10000111 11010011 00101101  00000001 01000111 11100001 01100000
//运行结果4:11100110 10000111 11010011 00101101  00000001 01101011 11011000 11101000
//运行结果5:11100110 10000111 11010011 00101101  00000000 10001010 11110110 11011000
//注:每次运行结果都不同,高4字节相同,低4字节开始有差异,有待研究论证!

6. 对指定文件中的数字,输出整除信息

//nums.txt
2 6 15 105 21 70 10 1

除穷举八种情况外,还可以像下面这样做。

//实现代码
#include<iostream>
#include<sstream>
#include<fstream>
using namespace std;
void main() {
	fstream in("nums.txt");
	for (string s; getline(in, s); ) {
		int number;
		for (istringstream sin(s); sin >> number; ) {
			bool A = number % 3, B = number % 5, C = number % 7;
			if (!A&&!B&&!C)
				cout << number <<" 该数能同时被3、5、7整除!" << "\n";

			if (!A && !B&&C || !A &&B && !C || A && !B && !C) {
				cout << number << " 该数能被";
				if (!A)cout << " 3 ";					
				if (!B)cout << " 5 ";					
				if (!C)cout << " 7 ";					
				cout << "整除!\n";
			}
				
			if (A && B && !C || A && !B && C || !A && B&&C) {
				cout << number << " 该数能被";
				if (!A)cout << " 3 ";				
				if (!B)cout << " 5 ";					
				if (!C)cout << " 7 ";					
				cout << "整除!\n";
			}
				
			if (A && B && C)
				cout << number <<" 该数不能被3、5、7任一个整除!" << "\n";
		}
	}
}

7. 将旧式C++程序编排成自己的风格,并写出运行结果

//修改结果
int a = -1, b = 3, c = 3;
int s = 0, w = 0, t = 0;
if (c > 0)
	s = a + b;//s = 2
if (a <= 0)
{
	if (b > 0) {
		if (c <= 0)
			w = a - b;
	}	
}
else {
	if (c > 0)
		w = a - b;
	else
		t = c;
}	
cout << s << "," << w << "," << t << endl;//2,0,0  w,t没有重新赋值

说明: 由于没有课后答案参照,这题是根据原来程序的运行结果修改的。

8. 将二进制数转换成十进制数

//aaa.txt
01010010000111110111110110110011001011111110011111100000001
00000000000000001111111110101010010101010010100000001111100
100001
-1
//样本输出:
184924582623264513  
8784594944124	
33

【方法1】

#include<iostream>
#include<iomanip>
#include<sstream>
#include<fstream>
#include<cmath>
using namespace std;

void main() {
	fstream in("aaa.txt");	
	for (string s; getline(in, s); ) {	
		double tmp=0.0;
		if (s == "-1")
			break;
		for (int i = 0; i < s.length(); i++) {
			if (s.at(i) == '1') {
				tmp += pow(2.0, double(s.length() - 1 - i));
			}
		}
		cout <<fixed <<setprecision(0)<< tmp << "\n";//取消科学计数法表示
	}
}
/*	运行结果:
	科学计数法表示:
	  1.84925e+17
      8.78459e+12
      33
    定点表示:
	  184924582623264512	  //这里与样本输出有差别 ,比样本输出小1
	  8784594944124	
	  33	  
*/	

样本输出 184924582623264513才是正确的,说明程序有问题。(有待研究)
在这里插入图片描述
【方法2】

//方法引入
string test = "10001001";
__int64 ans = 0;	
for (int i = 0; i<test.length(); i++) {
	ans = (ans << 1) + test[i] - '0'; //从最高位开始每次左移1位, 相当于乘以2
	cout << "test[i] - '0' 是" << test[i] - '0' << "  ,ans = "<<ans << "\n";
}
cout << ans << endl;
/* 运行结果:
	test[i] - '0' 是1  ,ans = 1
	test[i] - '0' 是0  ,ans = 2
	test[i] - '0' 是0  ,ans = 4
	test[i] - '0' 是0  ,ans = 8
	test[i] - '0' 是1  ,ans = 17
	test[i] - '0' 是0  ,ans = 34
	test[i] - '0' 是0  ,ans = 68
	test[i] - '0' 是1  ,ans = 137
	137
*/
void main(){
	fstream in("aaa.txt");
	for (string s;  getline(in, s); )
	{  
		__int64 ans = 0;//__int64是64位整数,范围是[-2^63, 2^63-1]
		if (s == "-1") {
			break;
		}
		for (int i = 0; i<s.length(); i++) {
			ans = (ans << 1) + s[i] - '0';
		}
		cout << ans << endl;
	}
	/*运行结果:
		184924582623264513    //结果正确
		8784594944124
		33
	*/
}

【方法3】

//测试long long类型
cout << sizeof(long long) << endl;//long long类型占8个字节

//测试计算过程
char* s = "10001001";
unsigned long long x = 0, tmp = 1;
for (int i = strlen(s); i--; tmp <<= 1) {//tmp <<= 1 相当于 tmp =  tmp << 1
	cout << "tmp = "<< tmp ;
	if (s[i] == '1') {
		x |= tmp;
		cout << " ,x = " << x ;
	}
	cout << endl;
}
cout << "x = " << x << endl;
//运行结果:
//	tmp = 1 ,x = 1
//	tmp = 2
//	tmp = 4
//	tmp = 8 ,x = 9
//	tmp = 16
//	tmp = 32
//	tmp = 64
//	tmp = 128 ,x = 137
//	x = 137
//
void mian(){
	fstream in("aaa.txt");
	for (char s[65]; in >> s && s[0] != '-';)
	{
		unsigned long long x = 0, tmp = 1;
		for (int i = strlen(s); i--; tmp <<= 1) {
		//tmp <<= 1 相当于 tmp =  tmp << 1
			if (s[i] == '1')
				x |= tmp;
		}	
		cout << x << "\n";
	}	
}
/*运行结果:
	184924582623264513    //结果正确
	8784594944124
	33
*/

小结: 方法1不太正确,虽然思路很对。(为啥不正确,有待研究)
           方法2与方法3都是用位操作实现的,结果是正确的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值