【測繪專用】四捨六入五成雙的C++實現
阿新 • • 發佈:2018-12-28
作為一名測繪專業的學生,在內業計算中經常遇到遇到小數點後保留幾位小數的問題。根據《工程測量實驗教程》(王宇會 著)一書,內業計算按“四捨六入,五前單進雙舍(或稱奇進偶不進)”的取捨規則進行尾數的取捨。如資料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; }
歡迎各位留言提意見