【问题标题】:How to compute a double precision float score from the first 8 bytes of a string in Python?如何从 Python 中字符串的前 8 个字节计算双精度浮点分数?
【发布时间】:2013-10-23 18:51:35
【问题描述】:

尝试从 Python 中的 UTF-8 编码字符串对象获取双精度浮点分数。这个想法是获取字符串的前 8 个字节并创建一个float,以便按分数排序的字符串将根据它们的前 8 个字节(或者可能是它们的前 63 位,在强制它们之后按字典顺序排列一切都是肯定的,以避免符号错误)。

例如:

get_score(u'aaaaaaa') < get_score(u'aaaaaaab') < get_score(u'zzzzzzzz')

我尝试使用左移和 XOR 以整数形式计算分数,但我不确定如何将其转换为 float 值。我也不确定是否有更好的方法来做到这一点。

应该如何计算字符串的分数才能满足我之前指定的条件?

编辑:字符串对象是 UTF-8 编码的(根据 @Bakuriu 的评论)。

【问题讨论】:

  • Unicode not 有“字节”,因此您的问题毫无意义。您可能是指某个 unicode 字符串的特定编码。在这种情况下,您必须指定编码。
  • 64 位是不可能的,因为并非所有 double 值都是可排序的;即使是 63 位也不太可能。有 56 位的可能性吗?
  • 绝对。我的最终目标是从字符串中获取尽可能多的数据,保持顺序,放入浮点数。这样,浮点分数将给出字符串的近似“绝对”分数。完全可以忍受:)

标签: python sorting unicode floating-point double


【解决方案1】:

float 不会给你 64 位的精度。请改用整数。

def get_score(s):
  return struct.unpack('>Q', (u'\0\0\0\0\0\0\0\0' + s[:8])[-8:])[0]

在 Python 3 中:

def get_score(s):
  return struct.unpack('>Q', ('\0\0\0\0\0\0\0\0' + s[:8])[-8:].encode('ascii', 'error'))[0]

编辑:

floats,6 个字符:

def get_score(s):
  return struct.unpack('>d', (u'\0\1' + (u'\0\0\0\0\0\0\0\0' + s[:6])[-6:]).encode('ascii', 'error'))[0]

【讨论】:

  • TypeError: 'str' does not support the buffer interface
  • @Bakuriu:你确定你用这段代码明白了吗?哪个版本的 Python?
  • @JuanCarlosCoto:首先你把它削减到 6 个字符,因为这是你可以获得的所有精度,除非你可以将使用的字符数限制为只有 98 个。然后你做一个天真的基本转换为数字,然后将该数字中的 53 位附加到 11 个 0。然后将 that 转换为 float.
  • @JuanCarlosCoto:你决定好要使用哪 98 个字符了吗?
  • @JuanCarlosCoto:没有参考资料,因为我是即时想出的。如果您想了解更多,我建议您在 REPL 中使用字符串切片。其余的是here
【解决方案2】:

您需要设置整个字母表并手动进行转换,因为转换为 base > 36 不是内置的,为此您只需定义要使用的完整字母表。例如,如果它是一个 ascii 字符串,您可以使用所有 ascii 表作为字母表,从输入字符串创建一个以 base 256 为基数的 long 的转换。

这里有一个完整功能的示例:string to base 62 number

此外,您在执行此操作时不必担心负正数,因为使用字母表中的第一个字符对字符串进行编码将产生表示中可能的最小数字,即负值与最高绝对值,在您的情况下为 -2**63,这是正确的值,并允许您使用 来对付它。

希望对你有帮助!

【讨论】:

  • 所以,为了确保我理解:获取字符串的前 8 个字符并将它们视为以 256 为基数的数字并将它们转换回以 10 为基数?
  • 是的,但是基数是由输入字符串中不同字符的数量定义的,例如,如果您只使用 128 个不同的字符,则可以使用基数 128。如果您事先不知道,则基数可能高于 256,最多以 utf-08 编码的所有可能的 unicode 字符(如果我没记错的话,基数为 1024)。
猜你喜欢
  • 1970-01-01
  • 2021-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多