将数组转换为以 0.x (C) 开头的数字

Convert the array to a number starting with 0.x (C)

提问人:Oxygen033 提问时间:11/25/2022 更新时间:11/27/2022 访问量:46

问:

我有一个函数,可以将输入数字的小数部分转换为另一个数字系统(不是最漂亮的代码):

void FracToAny(double D, int q, int t)
{
    double b[10] = {0};
    for (int i = 1; i < t; i++)
    {
        double DP = D * q;
        D = modf(DP, &b[i]);
        if (D == 0)
        {
            break;
        }
        D = DP - b[i];
    }
    for (int i = 0; i < t; i++)
    {
        if (q == 16)
        {
            switch ((int)b[i])
            {
            case 10:
                printf("A");
                break;
            case 11:
                printf("B");
                break;
            case 12:
                printf("C");
                break;
            case 13:
                printf("D");
                break;
            case 14:
                printf("E");
                break;
            case 15:
                printf("F");
                break;
            default:
                printf("%d", (int)b[i]);
                break;
            }
        }
    }
}

结果,我得到了一个 double 数组,它是生成的小数部分的逐个字符表示。但是,我想以“0.result”的形式从函数中返回此值。我该怎么做?

最好不要使用联合或动态内存分配(我已经看到他们试图找到问题的解决方案)。我想让它尽可能简单。

c 浮点 双精度

评论

0赞 Allan Wind 11/25/2022
如果您使用的是 linux,则可以使用 open_memestream 并使用 fprintf()。如果不想分配内存,则需要绑定上限大小并使用静态变量(不推荐)。另一个选项是让呼叫者为您分配内存(可能提供一种方法来告诉呼叫者您需要多少内存)。
0赞 Lundin 11/25/2022
不要打印,而是将结果存储在字符串中。然后打印该字符串并返回它。使用调用方分配的缓冲区是一种明智的方法。
0赞 unwind 11/25/2022
第一个循环从 1 开始,第二个循环从 0 开始,这可能不是最佳的。i
0赞 Steve Summit 11/26/2022
让调用方传入一个字符数组及其大小,函数将构造一个要返回的字符串。当你计算出一个字符(比如,在你的语句中),而不是立即将其打印出来,而是将字符存储到数组中。您也可以将前导“0.”存储到数组中。此外,请记住在构造的字符串末尾放置一个 null 终止字符。FracToAnyswitchprintf'\0'
0赞 Andrew 11/27/2022
您是否尝试打印 0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.A,0.B,0.C,0.D,0.E,0.F,用于 x.0,x.0625,x.125,x.1875,...x.8125、x.875、x.9375(和 0.0.0F 表示 0.99609375=255/256 等,我做十六进制数字)?modf 返回小数部分,但您将整数部分存储在数组中,这似乎是错误的。

答:

0赞 Andrew 11/27/2022 #1

我认为这就是您要做的(请参阅我上面的评论):

Mac_3.2.57$cat etFract.c
#include <stdio.h>
#include <math.h>

int main(void)
{
    int i;
    double D;
    int t = 3;
    double b[10] = {0};

    D = (3 * 16*16*16 + 4 * 16*16 + 5 *16)/(16*16*16.0);
    printf("translating %f...\n", D);

    for(i = 0; i < t; i++){
        b[i] = modf(D, &D);
        if(D == 0){
            break;
        }
        D = b[i] * 16;
    }
    printf("0.");
    for(int i = 0; i < t; i++){
        switch((int)b[i]*16){
            case 10:
                printf("A\n");
                break;
            case 11:
                printf("B\n");
                break;
            case 12:
                printf("C\n");
                break;
            case 13:
                printf("D\n");
                break;
            case 14:
                printf("E\n");
                break;
            case 15:
                printf("F\n");
                break;
            default:
                printf("%d", (int)(b[i]*16));
                break;
        }
    }
    printf("\n");
    return(0);
}
Mac_3.2.57$cc etFract.c
Mac_3.2.57$./a.out 
translating 3.269531...
0.450
Mac_3.2.57$