与 long 复制的位不同的两个双精度打印不同
Two doubles with bits copied differently from a long are printed differently
如下面的代码所示,我正在尝试使用不同的方法将位从长 longnum
复制到两个双打 d1
和 d2
:指针转换+ 分别取消引用和“按位与”。
# include <stdio.h>
int main(void) {
long longnum = 0xDDDDDDDDDDDDDDDD;
double d1 = *((double*)(&longnum));
double d2 = longnum & 0xFFFFFFFFFFFFFFFF;
printf("%ld\n\n",longnum);
printf("%lf\n\n",d1);
printf("%lf\n",d2);
return 0;
}
问题是两个双打的打印方式不同,如下面的输出所示。
-2459565876494606883
-1456815990147462891125136942359339382185244158826619267593931664968442323048246672764155341958241671875972237215762610409185128240974392406835200.000000
15987178197214945280.000000
考虑到 DBL_MAX
的大小,一个双打的最大大小,在我看来,这是一个巨大的数字,实际上是打印的两个双打的合理输出。
double d2 = longnum & 0xFFFFFFFFFFFFFFFF;
&
掩码没有任何作用。一个数字与全 1 的 AND 运算是相同的数字。上面的行与:
没有区别
double d2 = longnum;
该行没有进行任何重新解释。相反,它将 d2
设置为最接近代表 longnum
中的值的 double
。价值将是相似的;位模式将完全不同。
做你想做的事情的最好方法是加入工会。工会是执行 type punning.
的最佳方式
union {
long l;
double d;
} u;
u.l = longnum;
printf("%f\n\n", u.d);
像使用 d1
那样使用指针在技术上会调用未定义的行为。这是一个常见的习语,在实践中可能会很好地工作,但应该避免使用指针进行类型双关。
你的问题是
d1 = *((double*)(&longnum));
通过执行上述操作,您错误地从内存中获取内容,然后假设它是双精度格式。
如果您通过以下方式完成:
d1 = (double) longnum;
然后内存space longnum的内容,一个8字节整数,被正确转换然后存储 正确地存储在 d1 指向的位置的内存中。
然后 d1 的内容将是正确的。
建议您阅读有关 "Double-precision floating-point format"
的维基百科页面
浮点值(或双精度值)在内存中的存储方式与整数不同。
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
如下面的代码所示,我正在尝试使用不同的方法将位从长 longnum
复制到两个双打 d1
和 d2
:指针转换+ 分别取消引用和“按位与”。
# include <stdio.h>
int main(void) {
long longnum = 0xDDDDDDDDDDDDDDDD;
double d1 = *((double*)(&longnum));
double d2 = longnum & 0xFFFFFFFFFFFFFFFF;
printf("%ld\n\n",longnum);
printf("%lf\n\n",d1);
printf("%lf\n",d2);
return 0;
}
问题是两个双打的打印方式不同,如下面的输出所示。
-2459565876494606883
-1456815990147462891125136942359339382185244158826619267593931664968442323048246672764155341958241671875972237215762610409185128240974392406835200.000000
15987178197214945280.000000
考虑到 DBL_MAX
的大小,一个双打的最大大小,在我看来,这是一个巨大的数字,实际上是打印的两个双打的合理输出。
double d2 = longnum & 0xFFFFFFFFFFFFFFFF;
&
掩码没有任何作用。一个数字与全 1 的 AND 运算是相同的数字。上面的行与:
double d2 = longnum;
该行没有进行任何重新解释。相反,它将 d2
设置为最接近代表 longnum
中的值的 double
。价值将是相似的;位模式将完全不同。
做你想做的事情的最好方法是加入工会。工会是执行 type punning.
的最佳方式union {
long l;
double d;
} u;
u.l = longnum;
printf("%f\n\n", u.d);
像使用 d1
那样使用指针在技术上会调用未定义的行为。这是一个常见的习语,在实践中可能会很好地工作,但应该避免使用指针进行类型双关。
你的问题是
d1 = *((double*)(&longnum));
通过执行上述操作,您错误地从内存中获取内容,然后假设它是双精度格式。
如果您通过以下方式完成:
d1 = (double) longnum;
然后内存space longnum的内容,一个8字节整数,被正确转换然后存储 正确地存储在 d1 指向的位置的内存中。 然后 d1 的内容将是正确的。 建议您阅读有关 "Double-precision floating-point format"
的维基百科页面浮点值(或双精度值)在内存中的存储方式与整数不同。 https://en.wikipedia.org/wiki/Double-precision_floating-point_format