UVa 11809 Floating Point Numbers

UVa 11809 Floating Point Numbers

  浮点数的格式如下所示。如题所述一致,i 位长度存储尾数 m, (0.5m<1.0) ,j 位长度存储阶数 e 。
  
        | M(m,i位长度) | E(e,j位长度) |

  故数值N可以表示为: N=m×2e 。其中 m=1(1/2)i+1 e=2j1 。另一方面,题目所给输入为科学计数法所表示的数值,其数值可以表示为 M=A×10B (1.0A<10) 。故可得如下等式:

               N=M
             m×2e=A×10B
         logm10+e×log210=logA10+B
                K1=K2

  每一个i可以唯一决定一个m,每一个j可以唯一决定一个e,故每一对(i,j)可以唯一决定一对(m,e),从而可以唯一得出一个 K1 。所以本题应该列表,枚举出所有的(i,j)的组合可能。对题目输入的数计算出 K2 后进行查表,从而得出(i,j)。

AC代码如下(代码不算简洁,个人理解所写):

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

//#define DEBUG
double g_zero = 0.1;

struct Table {
    double value;
} g_table[10][31];

void init() 
{
    int i=0, j=0;
    int zero_cnt = 0;

    // 计算查找表
    for (i=0; i<10; i++) {
        for (j=1; j<31; j++) {
            double m = 1-pow(0.5, i+1);
            int e = pow(2,j)-1;
            g_table[i][j].value = log10(m)+e*log10(2);
        }
    }
#ifdef DEBUG
    printf("Table:\n");
    for (i=0; i<10; i++) {
        for (j=1; j<31; j++) {
            printf("  (%d,%d):%.15f\n", i, j, g_table[i][j].value);
        }
    }
#endif

    // 计算表项的最小差值,用于浮点数比较。
    for (j=1; j<31; j++) {
        for (i=1; i<10; i++) {
            if (g_zero > g_table[i][j].value-g_table[i-1][j].value) {
                g_zero = g_table[i][j].value-g_table[i-1][j].value;
            }
        }
    }
    for (zero_cnt=0; (int)g_zero==0; zero_cnt++,g_zero*=10); 
    for (i=0,g_zero=1.0; i<zero_cnt; i++,g_zero*=0.1);
#ifdef DEBUG
    printf("ZERO: %lf\n", g_zero);
#endif
}

int solve(double m ,int e)
{
    int i = 0, j = 0;
    double k = log10(m)+e;
#ifdef DEBUG
    printf("Solve Case:\n  K Value: %.15f (m:%.15f, e:%d)\n", k, m, e);
#endif
    for (i=0; i<10; i++) {
        for (j=1; j<31; j++) {
            if (k-g_table[i][j].value<g_zero && 
                    k-g_table[i][j].value>-g_zero) {
                printf("%d %d\n", i,j);
#ifdef DEBUG
                printf("\n");
#endif
                return 0;
            }
        }
    }
#ifdef DEBUG
    printf("No solve\n\n");
#endif
}

int main(int argc, char **argv)
{
    init();
    char data[1024];
    char *ptr = NULL;
    double m;
    int e;

    while (scanf("%s", data) == 1) {
        ptr=data;
        while (!(*(ptr)=='\0'||*(ptr)=='e')) ptr++;
        if (*(ptr) == 'e')  *ptr++ = '\0';
        sscanf(data, "%lf", &m);
        sscanf(ptr, "%d", &e);
#ifdef DEBUG
        printf("INPUT:%.15f - %d\n", m, e);
#endif
        if (e==0 &&(-g_zero<m&&m<g_zero))
            break;
        solve(m,e);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值