如何在Python 2.5中将浮点数转换为十六进制字符串?附有无效解决方案

2 投票
3 回答
6988 浏览
提问于 2025-04-15 12:31

我真正需要做的是把一个浮点数导出到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 个回答

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>
3

如果你在使用小端字节序的架构,

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

如果是大端字节序,就用 '>d' 代替 <d。无论哪种情况,这样做都会给你一个十六进制字符串,正如你在问题标题中所要求的那样,当然C语言的代码也能理解这个字符串;不过我不太明白那两个整数和“十六进制字符串”有什么关系。

6

这段Python代码看起来是正常工作的。问题出在C语言的代码上:你把long long填得没问题,但接下来你直接把整数值转换成浮点数,而不是重新解释字节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是用来表示long double的。

撰写回答