我正在尝试编写一个将实数转换为64位浮点二进制的代码。为此,用户输入实数(例如,547.4242),程序必须输出64位浮点二进制数。
我的想法:
这就是我被困住的地方。总结一下,我有:“整数部分= 1000100011”(类型为int)和“分数部分= 0110110010011000010111110000011011110110100101000100”(数组)。
我该怎么办?
答案 0 :(得分:0)
以下代码用于根据IEEE754表示法确定浮点数的内部表示。此代码在Turbo c ++ ide中生成,但您可以轻松转换为通用ide。
#include<conio.h>
#include<stdio.h>
void decimal_to_binary(unsigned char);
union u
{
float f;
char c;
};
int main()
{
int i;
char*ptr;
union u a;
clrscr();
printf("ENTER THE FLOATING POINT NUMBER : \n");
scanf("%f",&a.f);
ptr=&a.c+sizeof(float);
for(i=0;i<sizeof(float);i++)
{
ptr--;
decimal_to_binary(*ptr);
}
getch();
return 0;
}
void decimal_to_binary(unsigned char n)
{
int arr[8];
int i;
//printf("n = %u ",n);
for(i=7;i>=0;i--)
{
if(n%2==0)
arr[i]=0;
else
arr[i]=1;
n/=2;
}
for(i=0;i<8;i++)
printf("%d",arr[i]);
printf(" ");
}
有关详细信息,请点击here!
答案 1 :(得分:0)
诀窍是将值视为整数,因此将547.4242
读作无符号长long(即64位或更多),即5474242
,计算后的数字位数。 &#39;。&#39;,在这种情况下4.现在你有一个比它应该大10 ^ 4的值。所以你浮动5474242
(作为双倍或长双)并除以10 ^ 4。
十进制到二进制转换看似简单。当你有更多的位数而不是浮点数时,它将不得不舍入。当你有比64位整数更多的数字时会发生更多的乐趣 - 注意尾随的零是特殊的 - 你必须决定是否舍入(以及浮动时发生的舍入)。然后就是处理E +/- 99。然后,当你最终划分(或乘法)10 ^ n时,你有(a)另一个潜在的舍入,以及(b)你的浮动中表示大10 ^ n不是完全的问题点 - 这是另一个错误来源。 (对于E +/- 99表格,最后一步可能需要达到10 ^ 300以上。)
享受!
答案 2 :(得分:0)
为了将所有可能的十进制表示正确地舍入到最近的double
,您需要大整数。仅使用C中的基本整数类型将使您重新实现大整数算术。这两种方法都是可能的,关于每种方法的更多信息如下:
对于第一种方法,您需要一个大整数库:GMP是一个很好的库。使用这样一个大整数库,你可以处理一个输入,例如123.456E78作为整数123456 * 10 75 ,并开始想知道[2 53 中的M值是多少...... 2 54 )和[-1022 ... 1023]中的P使得(M / 2 53 )* 2 P 最接近该数目。这个问题可以通过大整数运算来回答,遵循this blog post中描述的步骤(摘要:首先确定P.然后使用除法来计算M)。完整的实现必须处理次正规数和无穷大(inf
是返回指数大于+1023的数字的任何十进制表示的正确结果。
第二种方法,如果您不想包含或实现完整的通用大整数库,仍然需要在表示大数的C整数数组上实现一些基本操作。此implementation中的函数decfloat()
表示基数10 9 中的大数字,因为这简化了从初始十进制表示到内部表示的转换,如数组x
uint32_t
。
答案 3 :(得分:0)
以下是基本转换。足够让OP开始。
OP的“实数的整数部分” - &gt; int
太有限了。最好将整个字符串简单地转换为像uintmax_t
这样的大整数。请注意小数点'.'
并考虑扫描时溢出。
此代码不处理指数也不处理负数。由于有限整数ui
或最终num = ui * pow10(expo)
,它可能在最后一位左右关闭。它处理大多数溢出情况。
#include <inttypes.h>
double my_atof(const char *src) {
uintmax_t ui = 0;
int dp = '.';
size_t dpi;
size_t i = 0;
size_t toobig = 0;
int ch;
for (i = 0; (ch = (unsigned char) src[i]) != '\0'; i++) {
if (ch == dp) {
dp = '\0'; // only get 1 dp
dpi = i;
continue;
}
if (!isdigit(ch)) {
break; // illegal character
}
ch -= '0';
// detect overflow
if (toobig ||
(ui >= UINTMAX_MAX / 10 &&
(ui > UINTMAX_MAX / 10 || ch > UINTMAX_MAX % 10))) {
toobig++;
continue;
}
ui = ui * 10 + ch;
}
intmax_t expo = toobig;
if (dp == '\0') {
expo -= i - dpi - 1;
}
double num;
if (expo < 0) {
// slightly more precise than: num = ui * pow10(expo);
num = ui / pow10(-expo);
} else {
num = ui * pow10(expo);
}
return num;
}