python 2.5:如何将浮点转换为十六进制?

python 2.5:如何将浮点转换为十六进制?,python,floating-point,hex,Python,Floating Point,Hex,我想使用python 2.4/2.5将time.time的输出转换为十六进制浮点值 我找到了大量将十六进制转换为浮点的示例,但我找不到任何可以让我像python的float.hex>=2.6那样做的东西。在2.6之前的python中,这是不可移植的;它需要sys.float_info中的信息,这在Python 2.6中是新的 如果您想以不可移植的方式执行此操作,即针对您的特定平台,您需要查看用于生成2.4/5 Python的C编译器的float.h文件,或者查看平台上2.6或2.7实现返回的sy

我想使用python 2.4/2.5将time.time的输出转换为十六进制浮点值


我找到了大量将十六进制转换为浮点的示例,但我找不到任何可以让我像python的float.hex>=2.6那样做的东西。

在2.6之前的python中,这是不可移植的;它需要sys.float_info中的信息,这在Python 2.6中是新的

如果您想以不可移植的方式执行此操作,即针对您的特定平台,您需要查看用于生成2.4/5 Python的C编译器的float.h文件,或者查看平台上2.6或2.7实现返回的sys.float_信息,并相信它适用于您的2.4/5 Python。然后,您需要查看Python源对象/floatobject.c中的float_hex函数,并将其转换为Python,然后在2.6/7 Python上测试它

这似乎是很多工作,为了什么?你的目标是什么?你想做什么是用repryour_float无法实现的

编辑:需要唯一标识符

请注意,time.time不是很精确:

一次又一次 以浮点数形式返回时间,以秒为单位表示,以UTC为单位。请注意,尽管时间始终以浮点数形式返回,但并非所有系统提供的时间精度都优于1秒。虽然此函数通常返回非递减值,但如果系统时钟已在两次调用之间设置回原位,则它可以返回比上一次调用更低的值。

允许高达十亿分之一的第二个决议:

>>> hex(int(time.time() * 1000000000))
'0x11ef11c41cf98b00L'
>>>

这足够好吗?

在2.6版之前,不能在Python中进行移植;它需要sys.float_info中的信息,这在Python 2.6中是新的

如果您想以不可移植的方式执行此操作,即针对您的特定平台,您需要查看用于生成2.4/5 Python的C编译器的float.h文件,或者查看平台上2.6或2.7实现返回的sys.float_信息,并相信它适用于您的2.4/5 Python。然后,您需要查看Python源对象/floatobject.c中的float_hex函数,并将其转换为Python,然后在2.6/7 Python上测试它

这似乎是很多工作,为了什么?你的目标是什么?你想做什么是用repryour_float无法实现的

编辑:需要唯一标识符

请注意,time.time不是很精确:

一次又一次 以浮点数形式返回时间,以秒为单位表示,以UTC为单位。请注意,尽管时间始终以浮点数形式返回,但并非所有系统提供的时间精度都优于1秒。虽然此函数通常返回非递减值,但如果系统时钟已在两次调用之间设置回原位,则它可以返回比上一次调用更低的值。

允许高达十亿分之一的第二个决议:

>>> hex(int(time.time() * 1000000000))
'0x11ef11c41cf98b00L'
>>>

这足够好吗?

这是代码的C版本,我现在没有时间移植它,但也许其他人可以

float_hex(PyObject *v)
{
    double x, m;
    int e, shift, i, si, esign;
    /* Space for 1+(TOHEX_NBITS-1)/4 digits, a decimal point, and the
       trailing NUL byte. */
    char s[(TOHEX_NBITS-1)/4+3];

    CONVERT_TO_DOUBLE(v, x);

    if (Py_IS_NAN(x) || Py_IS_INFINITY(x))
        return float_str((PyFloatObject *)v);

    if (x == 0.0) {
        if (copysign(1.0, x) == -1.0)
            return PyString_FromString("-0x0.0p+0");
        else
            return PyString_FromString("0x0.0p+0");
    }

    m = frexp(fabs(x), &e);
    shift = 1 - MAX(DBL_MIN_EXP - e, 0);
    m = ldexp(m, shift);
    e -= shift;

    si = 0;
    s[si] = char_from_hex((int)m);
    si++;
    m -= (int)m;
    s[si] = '.';
    si++;
    for (i=0; i < (TOHEX_NBITS-1)/4; i++) {
        m *= 16.0;
        s[si] = char_from_hex((int)m);
        si++;
        m -= (int)m;
    }
    s[si] = '\0';

    if (e < 0) {
        esign = (int)'-';
        e = -e;
    }
    else
        esign = (int)'+';

    if (x < 0.0)
        return PyString_FromFormat("-0x%sp%c%d", s, esign, e);
    else
        return PyString_FromFormat("0x%sp%c%d", s, esign, e);
}

这是代码的C版本,我现在没有时间移植它,但也许其他人可以

float_hex(PyObject *v)
{
    double x, m;
    int e, shift, i, si, esign;
    /* Space for 1+(TOHEX_NBITS-1)/4 digits, a decimal point, and the
       trailing NUL byte. */
    char s[(TOHEX_NBITS-1)/4+3];

    CONVERT_TO_DOUBLE(v, x);

    if (Py_IS_NAN(x) || Py_IS_INFINITY(x))
        return float_str((PyFloatObject *)v);

    if (x == 0.0) {
        if (copysign(1.0, x) == -1.0)
            return PyString_FromString("-0x0.0p+0");
        else
            return PyString_FromString("0x0.0p+0");
    }

    m = frexp(fabs(x), &e);
    shift = 1 - MAX(DBL_MIN_EXP - e, 0);
    m = ldexp(m, shift);
    e -= shift;

    si = 0;
    s[si] = char_from_hex((int)m);
    si++;
    m -= (int)m;
    s[si] = '.';
    si++;
    for (i=0; i < (TOHEX_NBITS-1)/4; i++) {
        m *= 16.0;
        s[si] = char_from_hex((int)m);
        si++;
        m -= (int)m;
    }
    s[si] = '\0';

    if (e < 0) {
        esign = (int)'-';
        e = -e;
    }
    else
        esign = (int)'+';

    if (x < 0.0)
        return PyString_FromFormat("-0x%sp%c%d", s, esign, e);
    else
        return PyString_FromFormat("0x%sp%c%d", s, esign, e);
}

当然,这可以通过便携方式完成,这只是数学。下面是如何包括证明其工作的测试

from __future__ import division

MAXHEXADECIMALS = 10

def float2hex(f):
    w = f // 1
    d = f % 1

    # Do the whole:
    if w == 0:
        result = '0'
    else:
        result = ''
    while w:
        w, r = divmod(w, 16)
        r = int(r)
        if r > 9:
            r = chr(r+55)
        else:
            r = str(r)
        result =  r + result

    # And now the part:
    if d == 0:
        return result

    result += '.'
    count = 0
    while d:
        d = d * 16
        w, d = divmod(d, 1)
        w = int(w)
        if w > 9:
            w = chr(w+55)
        else:
            w = str(w)
        result +=  w
        count += 1
        if count > MAXHEXADECIMALS:
            break

    return result


import unittest
class Float2HexTest(unittest.TestCase):

    def test_ints(self):
        assert float2hex(0x25) == '25'
        assert float2hex(0xFE) == 'FE'
        assert float2hex(0x00) == '0'
        assert float2hex(0x01) == '1'
        assert float2hex(0x14E7F400A5) == '14E7F400A5'

    def test_floats(self):
        assert float2hex(1/2) == '0.8'
        assert float2hex(1/13) == '0.13B13B13B13'
        assert float2hex(1034.03125) == '40A.08'

suite = unittest.makeSuite(Float2HexTest)
runner = unittest.TextTestRunner()
runner.run(suite)
是的,那是毫无意义的-
当然,在这种情况下,正确的答案不是将浮点转换为十六进制,而是使用时间的整数表示,并将其转换为十六进制字符串。但还是可以做到的

当然,这可以通过便携方式完成,这只是数学。下面是如何包括证明其工作的测试

from __future__ import division

MAXHEXADECIMALS = 10

def float2hex(f):
    w = f // 1
    d = f % 1

    # Do the whole:
    if w == 0:
        result = '0'
    else:
        result = ''
    while w:
        w, r = divmod(w, 16)
        r = int(r)
        if r > 9:
            r = chr(r+55)
        else:
            r = str(r)
        result =  r + result

    # And now the part:
    if d == 0:
        return result

    result += '.'
    count = 0
    while d:
        d = d * 16
        w, d = divmod(d, 1)
        w = int(w)
        if w > 9:
            w = chr(w+55)
        else:
            w = str(w)
        result +=  w
        count += 1
        if count > MAXHEXADECIMALS:
            break

    return result


import unittest
class Float2HexTest(unittest.TestCase):

    def test_ints(self):
        assert float2hex(0x25) == '25'
        assert float2hex(0xFE) == 'FE'
        assert float2hex(0x00) == '0'
        assert float2hex(0x01) == '1'
        assert float2hex(0x14E7F400A5) == '14E7F400A5'

    def test_floats(self):
        assert float2hex(1/2) == '0.8'
        assert float2hex(1/13) == '0.13B13B13B13'
        assert float2hex(1034.03125) == '40A.08'

suite = unittest.makeSuite(Float2HexTest)
runner = unittest.TextTestRunner()
runner.run(suite)
是的,那是毫无意义的-
当然,在这种情况下,正确的答案不是将浮点转换为十六进制,而是使用时间的整数表示,并将其转换为十六进制字符串。但还是可以做到的

如果你说了你为什么要这么做,比如什么会消耗十六进制字符串?我需要它和其他东西一起创建一个唯一的标识符。如果你想知道原因,答案是:这不是我的选择。如果你不需要从唯一id恢复时间,你只需要不同的时间产生不同的数字,请尝试hashtime.time获取整数,尝试hexhashtime.time获取“0xBLAHBLAH”形式的字符串。@Russell Borogove:aarrgghh hashx==hashy和x!=要评估为真。。。他希望它是唯一的如果你想要一个唯一的标识符,只需使用uuid模块-它就是为了这个原因而制造的。如果你说你为什么要这样做,这会有所帮助,例如,什么会消耗十六进制字符串?我需要它与其他东西一起创建一个唯一的标识符。如果您想知道为什么会这样,答案是:这不是我的选择。如果您不需要从唯一id恢复时间,并且您只希望不同的时间产生不同的数字,请尝试hashtime.time获取整数,尝试hexhashtime.time获取'0xBLAHBLAH'形式的字符串。@Ru
ssell Borogove:aarrgghh hashx==hashy和x!=要评估为真。。。他希望它是唯一的如果你想要一个唯一的标识符,只需使用uuid模块——它就是为了这个原因而设计的。