如何在Python 2.5中将Python float转换为十六进制字符串?附加非工作解决方案

时间:2009-06-27 16:21:38

标签: python double

我真正需要做的是将浮点数导出到C而没有精度损失。

我在python中做到了这一点:

import math
import struct
x = math.sqrt(2)
print struct.unpack('ii', struct.pack('d', x))
# prints (1719614413, 1073127582)

在C中我试试这个:

#include <math.h>
#include <stdio.h>

int main(void)
{
  unsigned long long x[2] = {1719614413, 1073127582};
  long long lx;
  double xf;

  lx = (x[0] << 32) | x[1];
  xf = (double)lx;
  printf("%lf\n", xf);
  return 0;
}

但在C中我得到:

7385687666638364672.000000而非sqrt(2)。

我错过了什么?

感谢。

3 个答案:

答案 0 :(得分:6)

Python代码似乎有效。问题出在C代码中:你已经填充了long long,但是你将整数值直接转换为浮点数,而不是将字节重新解释为{{1} }。如果你在它上面抛出一些指针/寻址就可以了:

double

另请注意,jkugelman$ cat float.c #include <stdio.h> int main(void) { unsigned long x[2] = {1719614413, 1073127582}; double d = *(double *) x; printf("%f\n", d); return 0; } jkugelman$ gcc -o float float.c jkugelman$ ./float 1.414214 (以及double)的格式说明符为float,而非%f%lf适用于%lf

答案 1 :(得分:3)

如果您的目标是小端架构,

>>> s = struct.pack('<d', x)
>>> ''.join('%.2x' % ord(c) for c in s)
'cd3b7f669ea0f63f'

如果是big-endian,请使用'>d'代替<d。在任何一种情况下,这都会给你一个十六进制字符串,正如你在问题标题中所要求的那样,当然C代码可以解释它;我不确定这两个整数与“十六进制字符串”有什么关系。

答案 2 :(得分:1)

repr()是你的朋友。

C:\junk\es2>type es2.c
#include <stdio.h>
#include <math.h>
#include <assert.h>

int main(int argc, char** argv) {
    double expected, actual;
    int nconv;
    expected = sqrt(2.0);
    printf("expected: %20.17g\n", expected);
    actual = -666.666;
    nconv = scanf("%lf", &actual);
    assert(nconv == 1);
    printf("actual:   %20.17g\n", actual);
    assert(actual == expected);
    return 0;
    }


C:\junk\es2>gcc es2.c

C:\junk\es2>\python26\python -c "import math; print repr(math.sqrt(2.0))" | a
expected:   1.4142135623730951
actual:     1.4142135623730951

C:\junk\es2>