问题描述
小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 0 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R 格式整数的做法是:
-
将浮点数乘以 2n;
-
四舍五入到最接近的整数。
输入格式
一行输入一个整数 n 和一个浮点数 d,分别表示转换参数,和待转换的浮点数。
输出格式
输出一行表示答案:d 用 R 格式表示出来的值。
cpp
#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;
// 从字符串的末尾开始遍历,将字符转换为整数并存入vector
for(int i=d.size()-1; i>=0; i--)
{
if(d[i]!='.')
b.push_back(d[i]-'0'); // 将字符型数字转换为整数型并存入vector
else{
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
高精度加减乘除的模版如下:
cpp
#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;
}
cpp
#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(); // 去掉前导0
return 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 >= B
auto C = sub(A, B);
for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
} else { // A < B
auto C = sub(B, A);
cout << "-";
for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
}
return 0;
}
cpp
#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(); // 去掉前导0
return 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;
}
cpp
#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(); // 去掉前导0
return 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。
-
乘法:大整数乘小整数,逐位相乘并处理进位。
-
除法:大整数除以小整数,逐位计算商和余数。