首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双精度的任意精度运算

双精度的任意精度运算
EN

Stack Overflow用户
提问于 2019-10-10 01:42:56
回答 1查看 56关注 0票数 0

所以我尝试使用任意精度的算术来表示双精度,通过指数和尾数,然后得到相同的双精度。

我尝试使用联合来获取尾数和指数:

代码语言:javascript
复制
typedef struct  s_arith
{
    long            mant:64;
    short           exp:15;
    char            sign:1;

}               t_arith;

union u_dbl
{
    t_arith         arith;
    long double     ldbl;
};

然后,我尝试使用下面的公式得到初始的双精度:(-1)^S *M*2^ E,但它对我不起作用。我做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2019-10-10 03:11:17

您的问题有多个问题:

所以我尝试使用任意精度算术,,,

long double不是任意的精度,它只是扩展的精度。任意精度是一种获取任意多个有效数字的机制(直到可用内存),而这里只有64位。

  1. long mant:64;

在32位系统上,这将无法编译,因为long可能是32位的。你应该使用unsigned long longuint64_t (注意无符号:有符号的位域可能会带来惊喜)。实际上,如果使用uint64_t,这不一定是位字段:类型本身恰好是64位宽。

  1. 在x87 80位格式中,就像在所有IEEE754二进制格式中一样,指数是有偏差的。特别是,在80位扩展精度x87格式中,表示1.0的偏置指数为0x3fff。因此,您不能简单地在此字段中输入一个0,然后期望该数字为r×2⁰。

考虑到这一点,我们可以编写一个修改了定义的示例:

代码语言:javascript
复制
#include <stdint.h>
#include <math.h>

typedef struct  s_arith
{
    uint64_t        mant;
    uint16_t        exp:15;
    uint8_t         sign:1;

}               t_arith;

union u_dbl
{
    t_arith         arith;
    long double     ldbl;
};

#include <stdio.h>

int main()
{
    const uint64_t mant=0xc000000000000000;
    const int expo=5;
    const union u_dbl d={mant,0x3fff+expo,0};
    printf("%Lg\n", d.ldbl);
}

这将在我的系统(带有gcc的32位x86 Linux )上输出48,正如预期的那样-因为有效数的最高两位被设置,其他位被清除,并且值是1.5×2⁵。

但实际上,要从整数有效位和指数可移植地加载浮点数,您应该使用<math.h>头中已经存在的函数:ldexp。下面是你如何做到这一点:

代码语言:javascript
复制
#include <stdint.h>
#include <stdio.h>
#include <math.h>

int main()
{
    const uint64_t mant=0xc000000000000000;
    const int expo=5;
    const long double x=ldexp(mant, expo-63);
    printf("%Lg\n", x);
}

这里的-63移位补偿了这样一个事实,即ldexp的第一个参数被用作要乘以2^(second_argument)的值,而不是简单地放入结果数字表示的有效数字字段中。

还要注意的是,即使在x86架构上,并不是所有的编译器都有80位的long double:例如,微软的编译器有64位的long double-与简单的double相同。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58309549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档