如何在C中进行精确的定点数计算?

问题描述 投票:0回答:1

如何在C中进行精确的定点数计算??

我使用C中的struct来存储整数部分和小数部分。

我猜函数不正确,可能没有正确处理溢出,但我不知道如何修改它。

输入如下:

3.14123412345 + 0.23
5.6324 - 6.43252
8.112 * 1.31

我的程序的输出完全错误。

这是我的代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#define maxn 110000
#define uint unsigned int
#define ull unsigned long long
typedef struct {
    int intgr;
    uint frac;
}PointFixedNum;
PointFixedNum a,b,ans;
char s1[maxn],s2[maxn],op;
double num1=0.0,num2=0.0;
void init(PointFixedNum *a,double num)
{
    a->intgr=(int)num;
    a->frac=(uint)((ull)(num-a->intgr)<<32);
}
void clear()
{
    a.frac=b.frac=ans.frac=0;
    a.frac=b.frac=ans.frac=0;
    num1=0.0;
    num2=0.0;
}
void read()
{
    scanf("%1100[^ ]",s1);
    scanf(" %c",&op);
    scanf("%1100s",s2);
    sscanf(s1,"%lf",&num1);
    sscanf(s2,"%lf",&num2);
}
PointFixedNum add(PointFixedNum a,PointFixedNum b)
{
    PointFixedNum c;
    ull sum=(ull)a.frac+b.frac;
    c.frac=(uint)(sum&((1ULL<<32)-1));
    c.intgr=a.intgr+b.intgr+(int)(sum>>32);
    return c;
}
PointFixedNum sub(PointFixedNum a,PointFixedNum b)
{
    PointFixedNum c;
    ull diff=(ull)a.frac-b.frac;
    c.frac=(uint)(diff&((1ULL<<32)-1));
    c.intgr=a.intgr-b.intgr-(int)(diff>>32);
}
PointFixedNum mul(PointFixedNum a,PointFixedNum b)
{
    PointFixedNum c;
    ull pro1=(ull)a.intgr*b.intgr;
    ull pro2=(ull)a.frac*b.frac;
    ull temp=(ull)((ull)pro1<<32)+(ull)pro2;
    c.intgr=(int)(temp>>32);
    c.frac=(uint)(temp&((1ULL<<32)-1));
}
void print(PointFixedNum a)
{
    double fraction=(double)a.frac/(1ULL<<32);
    double fin=(double)a.intgr+fraction;
    printf("%lf",fin);
}
int main()
{
    read();
    init(&a,num1);
    init(&b,num2);
    if(op=='+')
    {
        ans=add(a,b);
    }
    else if(op=='-')
    {
        ans=sub(a,b);
    }
    else if(op=='*')
    {
        ans=mul(a,b);
    }
    print(ans);
    return 0;
}
c c99 c11
1个回答
0
投票

代码至少存在这些问题:

不完全乘法

mul(PointFixedNum a,PointFixedNum b)
缺少
a.intgr*b.frac
*b.intgr*a.frac
部分。

打印不足

printf("%lf",fin);
打印 6 位小数部分,但固定分数是 232 中的 1 部分。 代码应在小数点右侧打印至少 10 位数字:
printf("%.10lf",fin);

© www.soinside.com 2019 - 2024. All rights reserved.