问题描述
小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 0 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R 格式整数的做法是:
-
将浮点数乘以 2n;
-
四舍五入到最接近的整数。
输入格式
一行输入一个整数 n 和一个浮点数 d,分别表示转换参数,和待转换的浮点数。
输出格式
输出一行表示答案:d 用 R 格式表示出来的值。
#include<bits/stdc++.h>
using namespace std; int main()
{int n;string d; // 数太大,用字符串来读取cin>>n>>d;vector<int> b; // 使用vector方便处理进位,可以在后面直接添加元素int sum=0, k=0;// 从字符串的末尾开始遍历,将字符转换为整数并存入vectorfor(int i=d.size()-1; i>=0; i--){if(d[i]!='.')b.push_back(d[i]-'0'); // 将字符型数字转换为整数型并存入vectorelse{k=sum; // 记录小数点的位置} sum++; // 记录当前处理的位数,为后续输出做准备}int u=b.size();// 进行n次乘以2的操作while(n--) { int t=0; // t用于存储进位for(int i=0; i<b.size(); i++){b[i] = b[i]*2 + t; // 当前位乘以2并加上进位if(b[i]>=10){t = b[i]/10; // 计算进位b[i] = b[i]%10; // 取余数作为当前位的值}else t=0; // 如果没有进位,t置为0}if(t) // 如果最后还有进位,添加到vector的末尾b.push_back(t);}u = b.size();int t=1;// 四舍五入处理if(k && b[k-1]>=5){ for(int i=k; i<u; i++){b[i] = b[i]+1; // 对小数点后的第一位进行四舍五入if(b[i]<=9){t=0;break;}else b[i] -= 10; // 如果进位后大于9,继续进位} if(t) // 如果最后还有进位,添加到vector的末尾b.push_back(t);}// 输出结果,从最高位开始输出for(int i=b.size()-1; i>=k; i--)cout<<b[i];return 0;
}
代码的逻辑很简单,就是把看d用高精度乘法的思路一直乘2
高精度加减乘除的模版如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;// 高精度加法
vector<int> add(vector<int>& A, vector<int>& B) {vector<int> C;int t = 0; // 进位for (int i = 0; i < A.size() || i < B.size(); i++) {if (i < A.size()) t += A[i];if (i < B.size()) t += B[i];C.push_back(t % 10); // 当前位的值t /= 10; // 进位}if (t) C.push_back(t); // 如果最后还有进位return C;
}int main() {string a, b;cin >> a >> b;vector<int> A, B;// 将字符串逆序存储到vector中for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');auto C = add(A, B); // 计算结果for (int i = C.size() - 1; i >= 0; i--) cout << C[i]; // 逆序输出return 0;
}
#include <iostream>
#include <vector>
using namespace std;// 判断A是否大于等于B
bool cmp(vector<int>& A, vector<int>& B) {if (A.size() != B.size()) return A.size() > B.size();for (int i = A.size() - 1; i >= 0; i--) {if (A[i] != B[i]) return A[i] > B[i];}return true;
}// 高精度减法
vector<int> sub(vector<int>& A, vector<int>& B) {vector<int> C;int t = 0; // 借位for (int i = 0; i < A.size(); i++) {t = A[i] - t;if (i < B.size()) t -= B[i];C.push_back((t + 10) % 10); // 当前位的值if (t < 0) t = 1; // 需要借位else t = 0;}while (C.size() > 1 && C.back() == 0) C.pop_back(); // 去掉前导0return C;
}int main() {string a, b;cin >> a >> b;vector<int> A, B;for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');if (cmp(A, B)) { // A >= Bauto C = sub(A, B);for (int i = C.size() - 1; i >= 0; i--) cout << C[i];} else { // A < Bauto C = sub(B, A);cout << "-";for (int i = C.size() - 1; i >= 0; i--) cout << C[i];}return 0;
}
#include <iostream>
#include <vector>
using namespace std;// 高精度乘法(大整数乘小整数)
vector<int> mul(vector<int>& A, int b) {vector<int> C;int t = 0; // 进位for (int i = 0; i < A.size() || t; i++) {if (i < A.size()) t += A[i] * b;C.push_back(t % 10); // 当前位的值t /= 10; // 进位}while (C.size() > 1 && C.back() == 0) C.pop_back(); // 去掉前导0return C;
}int main() {string a;int b;cin >> a >> b;vector<int> A;for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');auto C = mul(A, b); // 计算结果for (int i = C.size() - 1; i >= 0; i--) cout << C[i];return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;// 高精度除法(大整数除以小整数)
vector<int> div(vector<int>& A, int b, int& r) {vector<int> C;r = 0; // 余数for (int i = A.size() - 1; i >= 0; i--) {r = r * 10 + A[i];C.push_back(r / b); // 当前位的值r %= b; // 更新余数}reverse(C.begin(), C.end()); // 反转结果while (C.size() > 1 && C.back() == 0) C.pop_back(); // 去掉前导0return C;
}int main() {string a;int b;cin >> a >> b;vector<int> A;for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');int r; // 余数auto C = div(A, b, r); // 计算结果for (int i = C.size() - 1; i >= 0; i--) cout << C[i];cout << endl << r; // 输出余数return 0;
}
-
加法:逐位相加,处理进位。
-
减法:逐位相减,处理借位,注意结果的前导0。
-
乘法:大整数乘小整数,逐位相乘并处理进位。
-
除法:大整数除以小整数,逐位计算商和余数。