所以我尝试使用任意精度的算术来表示双精度,通过指数和尾数,然后得到相同的双精度。
我尝试使用联合来获取尾数和指数:
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,但它对我不起作用。我做错了什么?
发布于 2019-10-10 03:11:17
您的问题有多个问题:
所以我尝试使用任意精度算术,,,
long double不是任意的精度,它只是扩展的精度。任意精度是一种获取任意多个有效数字的机制(直到可用内存),而这里只有64位。
long mant:64;在32位系统上,这将无法编译,因为long可能是32位的。你应该使用unsigned long long或uint64_t (注意无符号:有符号的位域可能会带来惊喜)。实际上,如果使用uint64_t,这不一定是位字段:类型本身恰好是64位宽。
1.0的偏置指数为0x3fff。因此,您不能简单地在此字段中输入一个0,然后期望该数字为r×2⁰。考虑到这一点,我们可以编写一个修改了定义的示例:
#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。下面是你如何做到这一点:
#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相同。
https://stackoverflow.com/questions/58309549
复制相似问题