OpenJudge NOI 1.13 03:八进制小数

【题目链接】

OpenJudge NOI 1.13 03:八进制小数

【题目考点】

1. 数制

【解题思路】

八进制小数按位权展开式为 0. d 1 d 2 d 3 . . . d k = d 1 ∗ 8 − 1 + d 2 ∗ 8 − 2 + . . . + d k ∗ 8 − k 0.d_1d_2d_3...d_k=d_1*8^{-1}+d_2*8^{-2}+...+d_k*8^{-k} 0.d1d2d3...dk=d181+d282+...+dk8k
设位权为q,初值为1。
循环遍历8进制数字字符串,每次循环q除以8。
第一次循环q除以8变为 8 − 1 8^{-1} 81,取到数字 d 1 d_1 d1,把 d 1 ∗ q d_1*q d1q加到结果中。
第二次循环q除以8变为 8 − 2 8^{-2} 82,取到数字 d 2 d_2 d2,把 d 2 ∗ q d_2*q d2q加到结果中。

第k次循环q除以8变为 8 − k 8^{-k} 8k,取到数字 d k d_k dk,把 d k ∗ q d_k*q dkq加到结果中。
最后输出结果。
题目要求k的范围为 0 < k < 15 0<k<15 0<k<15,最大为14。根据八进制与二进制的转化关系,1位8进制数字对应3位2进制数字,所以14位8进制数字最多可以转化为42位二进制数字。
考虑c++ double类型的存储原理(参考:c++ double类型存储),double类型尾数有52位,如果只是表示二进制数字,精度可以达到52位二进制数字。本题结果最多是精度为42位的二进制数字,因此使用double类型一定可以正确表示。
输出时,要最多保留42位小数,但如果小数点后位数不足42位,末尾也不要补0。这就不能用固定保留的位数的写法。如果写cout,不能写fixed,只写setprecision(42);如果写printf,不能写%.42f,只能写%.42g

【题解代码】

解法1:用cin,cout
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    double q = 1, ans = 0;//q:位权 
    cin >> s;
    for(int i = 2; i < s.length(); ++i)
    {
        q /= 8;
        ans += q * (s[i] - '0');
    }
    cout << s << " [8] = " << setprecision(42) << ans << " [10]";
    return 0;
}
解法2:用scanf, printf
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s[20];
    scanf("%s", s);
    int len = strlen(s);
    double q = 1, ans = 0;//q:位权 
    for(int i = 2; i < len; ++i)//从十分位开始遍历 
    {
        q /= 8;
        ans += q * (s[i]-'0');
    }
    printf("%s [8] = %.42g [10]", s, ans);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值