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

发布于 2024-10-07 17:44:13 字数 162 浏览 2 评论 0原文

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

我找到了大量将十六进制转换为浮点数的示例,但我找不到任何可以让我执行 python >= 2.6 的 float.hex() 功能的内容。

I want to convert a float (the output of time.time()) in hex using python 2.4/2.5.

I found tons of examples that convert hex to float, but I cannot find anything that allows me to do what the float.hex() of python >= 2.6 does.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

挽心 2024-10-14 17:44:13

在 2.6 版本之前的 Python 中无法移植;它需要 sys.float_info 中的信息,这是 Python 2.6 中的新功能。

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

这看起来工作量很大,为了什么?你的目标是什么?您想要做哪些 repr(your_float) 无法实现的事情?

编辑:需要唯一标识符

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

“””
时间.time()
以浮点数形式返回时间,以 UTC 格式自纪元以来的秒数表示。请注意,尽管时间始终以浮点数形式返回,但并非所有系统都提供比 1 秒更好的时间精度。虽然此函数通常返回不递减的值,但如果系统时钟在两次调用之间被调回,则它可能返回比前一次调用更低的值。
"""

允许高达十亿分之一的第二分辨率:

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

这足够好吗?

It can't be done portably in Python before version 2.6; it needs the information in sys.float_info, which is new in Python 2.6.

If you want to do it non-portably, i.e. for your particular platform, you would need to look at the float.h file for the C compiler that was used to produce your 2.4/5 Python, or at the sys.float_info returned by a 2.6 or 2.7 implementation on your platform (and trust that it applies to your 2.4/5 Python). Then you would need to look at the float_hex function in the Python source (Objects/floatobject.c) and translate that to Python and test it (against a 2.6/7 Python, perhaps).

This seems like a lot of work, for what? What is your goal? What do you want to do that can't be achieved with repr(your_float)?

Edit: need for a unique identifier

Note that time.time() is not very precise:

"""
time.time()
Return the time as a floating point number expressed in seconds since the epoch, in UTC. Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.
"""

Allowing for up to a billionth of a second resolution:

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

Is that good enough?

呆头 2024-10-14 17:44:13

这是代码的 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);
}

Here is the C version of the code, I don't have time to port it right now, but maybe someone else can.

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);
}
倾`听者〃 2024-10-14 17:44:13

当然它可以以可移植的方式完成,这只是数学。以下是方法(包括证明其有效的测试)。

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)

是的,那是毫无意义的。 :-)
当然,在这种情况下,正确的答案是不将浮点数转换为十六进制,而是使用时间的 INTEGER 表示形式并将其转换为十六进制字符串。但仍然可以做到。 :)

Of course it can be done in a portable way, it's just maths. Here's how (inclusing tests proving it works).

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)

Yeah, that's pretty pointless. :-)
Of course, the correct answer in this case is to not convert a float to hex, but to use an INTEGER representation of time and convert that to a hex string. But still, it can be done. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文