【问题标题】:converting negative float numbers to unsigned int将负浮点数转换为无符号整数
【发布时间】:2013-08-23 22:32:56
【问题描述】:

我正在尝试将无符号整数数据从 C 服务器发送到 python 客户端。要求是向客户端发送一个负浮点值。目前这个数字是 -5.700,我有 2 个问题。 1)我不知道如何在 uint32_t 中保留负性,我使用 MSB 作为标志位来解决它。这样好吗?谁有更好的建议?

2) 我尝试将 float 5.700 类型转换为 uint32_t,即 uint32_t fops = *(uint32_t*)(&float_var) //float_var is 5.700 并且 fops 被分配了值 0x00..40b66666,该值正在发送到 python 客户端。现在如何在客户端从这个值中取回浮点数?

更新:正如 Mats 建议的那样,python struct unpacks -ve 完美浮动,因此无需使用标志位。

【问题讨论】:

  • 你是如何进行传输的,为什么涉及 uint32_t?
  • 客户端/服务器通信通常通过 TCP(有时是 UDP)进行。 TCP 是一个字节序列。要发送浮点数,您必须(以某种方式)将浮点数转换为字节序列,传输该序列,然后重新组装浮点数。你如何做到这一点取决于你。 (虽然现在有几个库可以做这样的事情,比如 JSON、BSON、Protocol Buffers、MessagePack……)如果你能澄清你在做什么,以及你正在与什么协议进行通信会很好。跨度>
  • 另外,你确定那个演员表是 0x00006666 / 26214 吗?这很可能对应于 3.6-ish * 10^-41 的浮点数。 0xc0b666660x40b66666 更有可能。
  • 传输是通过 tcp 套接字进行的,但我遵循一个协议,该协议在位级别定义数据,因此是无符号值。服务器是用 c 编写的,我使用 tcp 发送 unint 数据并使用 python struct 解包它们。
  • Python 结构有一个浮点类型,可能适合你。发送 4 个字节,在 python 端将其称为浮点数,看看会发生什么。如果你的两台机器就什么是浮点数达成一致,那么它应该可以工作。

标签: python c sockets unsigned


【解决方案1】:

最简单的解决方案几乎总是最好的:将其设为字符串,然后传输它,而不是二进制浮点表示。这样,您就不必担心浮点表示的差异或如何让 Python “理解”您的二进制浮点值。

Edit1:但是,如果您将 32 位整数传输到 Python data 对象:我希望 floatdata = struct.unpack("f", data) 可以解决问题。

Edit2:struct.unpack(和 struct.pack)的文档

Edit3:struct.unpack 确实假定两台机器使用相同的浮点格式。这意味着该软件不能广泛移植。但它在最常用的平台上应该可以正常工作。

【讨论】:

  • 我同意如果该选项可用,这会更好。我理解需要以一种可以被 Python 解码的方式以无符号 32 位类型传输浮点数。
  • 我也同意打包和解包工作得很好,只要客户端和服务器系统是同构的。
  • 是的,就是这样。如果不是,修复起来会非常复杂——例如,一台具有 36 位 float 的机器无法真正将其发送到具有 32 位浮点数的机器。这就是为什么使用基于文本的解决方案将是更好的选择。
  • 好吧,你可以发送它,如果你愿意忍受截断(即舍入)。我能看到的唯一要求是交付给客户端的数据必须适合 32 位。
  • 它不一定只是截断 - 36 位可以以不同的方式组织,例如使用 9 位表示指数等。
【解决方案2】:

C 端的转换只是将代表浮点数的 4 个字节粘贴到 fops 变量中进行传输。您以某种方式将其传输到 python 客户端,它仍然是代表浮点数的 4 个字节。您可以使用 struct 模块获取这 4 个字节并构建一个 python 浮点数。

(编辑)高位是问题所在。 uint32_t 转换离开了高位,一旦设置为 (0xc0b66666) 而不是 (0x40b66666),它就可以在 python 中正常工作。因此,您可以手动设置 MSB,它应该可以工作。

>>> import struct
>>> buf=struct.pack('i', 0xc0b66666) # this is like the C cast to uint32_t
>>> len(buf)
4
>>> struct.unpack('f', buf)[0]
-5.699999809265137

【讨论】:

  • 草稿。我在意识到你的签名是你试图解决的唯一问题之前输入了这个。
  • 正是这样做以获得正浮动。这很好用
  • struct unpack 也适用于负数。 32 位浮点数的符号在最高位编码,因此使用0xc0b66666 应该给出正确的负数。当然,就像我在下面的回答中所说的那样,这假设发送和接收机器都具有相同的浮点格式。不能保证。
  • ...和设置 MSB 得到否定。天啊,如果我不得不为你的演员阵容为何如此高位而挠头的话,我的 C 已经生锈了。
  • @MatsPetersson - 确实!
【解决方案3】:

您可以使用 C 数学函数 frexpf() 来提取 float 的指数和尾数。然后,您可以在 Python 中使用ldexp() 来重构两者。

指数以有符号整数形式返回,尾数为区间[.5, 1)[-.5, -1) 中的有符号浮点数,具体取决于float 的符号。

您决定如何将此信息与 32 位无符号数字进行编码和解码,这取决于您。但是,假设您允许尾数使用 16 位。然后,可以将尾数乘以 215,然后用这 16 位来表示2's complement 中结果的四舍五入整数值。然后接收器可以将 16 位转换为有符号整数,然后除以 215

32 位中的其他 16 位也可用于表示 2 补码中的指数。

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    相关资源
    最近更新 更多