【每日一题】 UVA - 11809 Floating-Point Numbers 阅读题+取对数处理爆double

 

https://cn.vjudge.net/problem/UVA-11809

题意:很长orz

 

题解:算一下输入范围,发现用double是读不进来的,在这里wa了半天,(double 1e300  longdouble 1e4000)这题会1e20201780 orz

所以分别读入mantissa a和 exponent b,然后取对数得到一个等式:log(a) + b*log(10)==log(m) + e * log(2),其中m,e是答案,因为范围很小,可以直接二重循环暴力找。打表可以优化一点。

 

坑:标程是用公式的 ,懒得推,虽然我一开始也是用公式。。。

 常识性错误,不知道c++里写作log读作ln,卡了半天 orz

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
#include<set>
#include<bitset>
using namespace std;

#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eps 1e-7int main()
{
     double a,b;    
    while (~scanf("%17lfe%lf",&a,&b)&&(b || a)) {
         a = log(a) + b*log(10);
        rep(i, 1, 30)rep(j, 0, 9) {
             double m = 0, e = 0;
            rep(jj, 0, j)m += 1, m /= 2;
            rep(ii, 1, i)e *= 2, e += 1;
            if (abs(a- log(m) - e * log(2))<eps)cout << j << ' ' << i << endl;

        }
    }
    
}
/*
5.699141892149156e76
9.205357638345294e18
0e0

5 8
8 6


6.741349255732847e307
1.937500000000000e0
8.970910077290883e307
2.734479740168092e20201780
5.443088840828674e2465
7.100722886226033e80807123
7.499999999999997e0
4.461493107584252e4931
7.930743765436021e78912
1.638399999999996e4
6.284909967160199e153
5.794969071594055e40403561
7.874999999999996e0
7.049550013794259e78912
5.205075292180178e4931
2.094479696316021e323228496
5.999999999999998e0
7.513237239003285e19727
2.065788087458129e323228496
5.112881885711930e2465

1 10
4 1
8 10
0 26
8 13
6 28
3 2
1 14
5 18
0 4
3 9
4 27
5 2
2 18
2 14
8 30
1 2
1 16
5 30
3 13
*/

wa的代码

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

const double eps = 1e-4;
int main()
{
    double a,b;
    while (cin>>a&&a))
    {
        int cnt = 0, cnt2 = 0;
        a = a * pow(10, b);
        while (abs(a -1)> eps)a/=2,cnt++;
    
        cnt++;
        while (cnt)cnt >>= 1, cnt2++; cnt2--;
        cnt = 0;
        while (abs(a-1/2)>eps)
            a *= 2, a -= 1, cnt++; cnt--;
        cout <<cnt<<' '<< cnt2<<endl;
}
    
    return 0;
}
/*

5.699141892149156e76
9.205357638345294e18
0e0

*/

 

转载于:https://www.cnblogs.com/SuuT/p/9451892.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值