在Python2.5中,如何将Python浮点转换为十六进制字符串?附加非工作溶液

在Python2.5中,如何将Python浮点转换为十六进制字符串?附加非工作溶液,python,double,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) { un

我真正需要做的是将浮点数导出到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;
}
#包括
#包括
内部主(空)
{
无符号长x[2]={17196144131073127582};
长lx;
双xf;

lx=(x[0]Python代码似乎可以工作。问题在于C代码中:正确填写了
long
,但随后将整数值直接转换为浮点值,而不是将字节重新解释为
双精度
。如果对其抛出一些指针/寻址,则可以工作:

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
jkugelman$cat float.c
#包括
内部主(空)
{
无符号长x[2]={17196144131073127582};
双d=*(双*)x;
printf(“%f\n”,d);
返回0;
}
jkugelman$gcc-o float.c
jkugelman$/浮动
1.414214

还请注意,
double
(以及
float
)的格式说明符是
%f
,而不是
%lf
%lf
是用于
长双精度

,如果您的目标是一个小的endian架构

>>> s = struct.pack('<d', x)
>>> ''.join('%.2x' % ord(c) for c in s)
'cd3b7f669ea0f63f'
>>s=struct.pack('d')
而不是
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>
C:\junk\es2>键入es2.C
#包括
#包括
#包括
int main(int argc,字符**argv){
双预期,实际;
int NCOV;
预期=sqrt(2.0);
printf(“预期值:%20.17g\n”,预期值);
实际=-666.666;
nconv=scanf(“%lf”&实际值);
断言(nconv==1);
printf(“实际值:%20.17g\n”,实际值);
断言(实际==预期);
返回0;
}
C:\junk\es2>gcc es2.C
C:\junk\es2>\python26\python-C“导入数学;打印报告(math.sqrt(2.0))”;a
预计:1.4142135623730951
实际:1.4142135623730951
C:\junk\es2>

我试过使用long(拧紧前),我知道发生了什么!我使用的是64位(AMD64)和sizeof(long)==8。所以我需要在这里使用无符号int。谢谢!@Nelson:为了便于移植,你真的应该使用大小定义的类型,而不是在你的平台上恰好大小合适的类型-也不能保证int是32位的。C99标准定义了像uint32_t(在stdint.h中)这样的类型这在所有平台上都适用,其中double是标准的64位IEEE double。在python方面,在结构字符串前面加“=”将始终导致它使用固定大小(即“I”=32位无符号int),或“”使用固定端号(“=”使用本机端号,因此应与C编译器匹配).Alex,谢谢你的评论。你的回答也有帮助。我实际上需要的是导出到C(生成代码)。这样我就可以使用0xcd3b7f669ea0f63f(C中的long-long)…嗯,我更喜欢使用数字,这样我就不必关心endianness,但它也很有帮助。你必须关心endianness--你会把这两个32位数字按什么顺序排列?对:-)现在我在同一台机器上生成东西并生成输出。但我必须关心..你在生成C代码吗?只需从Python中将值打印为字符串,让C编译器高效地存储文本。这比C中的字节->双转换更简单、更快。好吧,我对我的C不太熟悉,这是肯定的,但e有什么问题吗将其导出为字符串并在C中将其转换为双精度?