UVa 11809 Floating Point Numbers

来源:互联网 发布:加内特2004季后赛数据 编辑:程序博客网 时间:2024/05/29 03:23

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+1e=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 DEBUGdouble 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
原创粉丝点击