【测绘专用】四舍六入五成双的C++实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34844814/article/details/79219525

作为一名测绘专业的学生,在内业计算中经常遇到遇到小数点后保留几位小数的问题。根据《工程测量实验教程》(王宇会 著)一书,内业计算按“四舍六入,五前单进双舍(或称奇进偶不进)”的取舍规则进行尾数的取舍。如数据1.1235和1.1245小数点后保留三位时,均应为1.124

//四舍六入五成双的基于C++11的实现
//C++11中sprintf、strncpy由于VS2015会报错,所以在这里改用sprintf_s、strncpy_s

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;

const int n = 1000;  //设置要保留的位数
char s1[20];
char s2[20];

int main()
{
double a1, a2, a3;
cin >> a1;
a2 = a1*n;               //将输入的数据乘以n,使得小数点后的第一位使我们要判断的是否为5的数
sprintf_s(s1, "%lf", a2);  //将double类型的a2打印到字符数组s1里面去
int b = strcspn(s1, ".");  //整型b即为小数点在字符数组中序号
char c = s1[b + 1];      //字符c即为小数点后一位数

if (c<'5')         //如果c小于5,则后面的舍去
{
strncpy_s(s2, s1, b);
a3 = atof(s2);
}
else
{
if (c>'5')  //如果c大于5,则进1
{
strncpy_s(s2, s1, b);
a3 = atof(s2) + 1;
}
else
{
//如果c大、等于5,则对前一位数进行判断奇偶
c = s1[b - 1];
if ((c % 2) != 0)  //C前一位为奇则进1
{
strncpy_s(s2, s1, b);
a3 = atof(s2) + 1;
}
else
{
strncpy_s(s2, s1, b);
a3 = atof(s2);
}
}

}
a3 = a3 / n;
cout << a3 << endl;  //输出结果
return 0;
}

//四舍六入五成双的C++实现

虽然实现了这个功能,不过有时候觉得还是很难用,所以将上面的程序封装成函数

//四舍六入五成双的基于C++11的实现封装成函数

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;

double SSLR(double s1, int a)
{
	int n;
	switch (a)
	{
	case 1:
		n = 10; break;
	case 2:
		n = 100; break;
	case 3:
		n = 1000; break;
	default:
		n = 1;
		break;
	}


	//设置要保留的位数
	double s2 = s1*n;               //将输入的数据乘以n,使得小数点后的第一位使我们要判断的是否为5的数
	double s3;
	char c1[20];
	char c2[20];


	sprintf_s(c1, "%lf", s2);  //将double类型的a2打印到字符数组s1里面去
	int b = strcspn(c1, ".");  //整型b即为小数点在字符数组中序号
	char c = c1[b + 1];      //字符c即为小数点后一位数


	if (c<'5')         //如果c小于5,则后面的舍去
	{
		strncpy_s(c2, c1, b);
		s3 = atof(c2);
	}
	else
	{
		if (c>'5')  //如果c大于5,则进1
		{
			strncpy_s(c2, c1, b);
			s3 = atof(c2) + 1;
		}
		else
		{
			//如果c大、等于5,则对前一位数进行判断奇偶
			c = c1[b - 1];
			if ((c % 2) != 0)  //C前一位为奇则进1
			{
				strncpy_s(c2, c1, b);
				s3 = atof(c2) + 1;
			}
			else
			{
				strncpy_s(c2, c1, b);
				s3 = atof(c2);
			}
		}


	}
	s3 = s3 / n;
	//cout << s3 << endl;  //输出结果
	return s3;
}

int main()
{
	double d1, d2, d3;
	cin >> d1;
	d2=SSLR(d1);
	cout << d2 << endl;
	return 0;
}

/***手动分割线    2018.5.1修改***/

其实上面的SSLR函数代码也可以根据不同的需要来进行修改。

参加过一次测绘程序程序设计竞赛后,便发现这个程序还不够完善,因为double类型默认输出位数只有六位,保留三位小数后超出了六位输出就会出问题(我是在计算前方交会的时候遇到的),便只好用头文件iomanip里的setprcision来解决了

#include <iostream>
#include "shuce.h"
#include <iomanip>
#include <string.h>
//#include <string>

using namespace std;

int main()
{
	char c[16];
	long double s;
	cin >> s;
	 double s1=SSLR(s, 3);
	 sprintf_s(c,"%lf",s1);
	 //int l0 = strlen(c);
	 int l = strcpy_s(c,".");
	 cout << s << endl;;
	cout << fixed<<setprecision(l+3)<<s1 << endl;    //注意l+3这里,加的数值应与前面保留的位数相对应
	//cout << s;
	return 0;
}



欢迎各位留言提意见 

猜你喜欢

转载自blog.csdn.net/qq_34844814/article/details/79219525