RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1192360
Accepted
Mikhail Murugov
Mikhail Murugov
Asked:2021-10-19 19:41:09 +0000 UTC2021-10-19 19:41:09 +0000 UTC 2021-10-19 19:41:09 +0000 UTC

如何在不丢失信息的情况下将浮点数表示为整数?

  • 772

有一个任务是在不丢失信息的情况下将float值转换为类型值int(一个float值到一个int值),即,这样您就可以执行反向转换。如何实施?

重要的

在这种转换过程中必须保留顺序和总和,
即 对于任何a, b: float应该执行:

to_float(to_int(a) + to_int(b)) == a + b

to_int(a) < to_int(b) при a < b и т.д.

我在英文 SO 上找到了答案,其中float值结构是一点一点表示的,但我无法想象它如何应用于我的任务。

注意:我的任务也不NaN需要inf转换。


解决方案尝试

最初,想到用这些字节序列化pickle.dumps然后int从这些字节中获取,但这根本不是一个合理的解决方案,它根本不满足要求。

已经尝试通过数字的字节表示来实现这一点(Qwertiy♦ 的答案),它不存储总和。

python
  • 6 6 个回答
  • 10 Views

6 个回答

  • Voted
  1. Qwertiy
    2021-10-20T00:44:07Z2021-10-20T00:44:07Z
    to_float(to_int(a) + to_int(b)) == a + b
    to_int(a) < to_int(b) при a < b и т.д.
    

    我记得在 python 中整数是无限的。Double的每次幂为11 位,这意味着当乘以 2**(2**12) 时,您会得到一个可以放入 int 的整数。只需要在翻译时相乘,而不是小数 - 否则会发生溢出。

    • 2
  2. Qwertiy
    2021-10-19T20:00:48Z2021-10-19T20:00:48Z

    您只需要将浮点数的二进制表示重新解释为整数。

    基于https://stackoverflow.com/a/14431225/4928642

    import struct
    
    def floatBits(f):
      s = struct.pack('>f', f)
      return struct.unpack('>l', s)[0]
    

    基于https://stackoverflow.com/a/58362843/4928642

    import ctypes
    
    def floatBits(x):
      f = ctypes.c_float(x)
      return ctypes.c_int.from_address(ctypes.addressof(f)).value
    

    这种转换不会保存总和:(

    lhs = random.getrandbits(30)
    rhs = random.getrandbits(30)
    assert int_to_float(lhs) + int_to_float(rhs) == int_to_float(lhs + rhs)
    

    它不应该。总的来说,它不会证明它可以节省。

    • 1
  3. CrazyElf
    2021-10-19T21:06:15Z2021-10-19T21:06:15Z

    而且你不想存储在两个整数中是徒劳的。在 Python 中甚至有一个专门的库。它可以将任何float数字表示为精确的分数,并以完全自然的方式处理这些数字:

    from fractions import Fraction
    
    print(Fraction(0.123456789))
    # 8895999182988127/72057594037927936
    
    print(float(Fraction(8895999182988127, 72057594037927936)))
    # 0.123456789
    
    • 1
  4. Best Answer
    vp_arth
    2021-10-27T22:29:18Z2021-10-27T22:29:18Z

    最简单的方法是简单地乘以和除以一个足够大的因子以覆盖所需的值范围。

    ratio = (1 << 156)
    
    def to_int(f):
        """ Если точности недостаточно, может вернуть 0 или бросить OverflowError при конвертации получившейся при умножении бесконечности
        """
        return int(f * ratio)
    
    def to_float(d):
        return d / ratio
    
    
    def to_int_2(f):
        r = (f * ratio).as_integer_ratio()
        assert r[1] == 1, 'Not enough precision'
        return r[0]
    

    几句话:

    # На некоторых ratio мы таки будем получать получать ровно 0.3 при сложении, так что тут поведение нестабильно    
    assert to_float(to_int(0.1) + to_int(0.2)) == 0.1 + 0.2
    
    assert to_float(to_int(-1.03e-30) + to_int(-2.04e-31)) == (-1.234e-30)
    assert to_float(to_int(-1.03e+130) + to_int(-2.04e+129)) == (-1.234e+130)
    
    
    assert to_int(1e-300) == 0
    try:
        print(to_int(1e+300))
    except OverflowError as e:
        assert str(e) == 'cannot convert float infinity to integer'
    
    # to_int_2
    assert to_float(to_int_2(0.1) + to_int_2(0.2)) == 0.1 + 0.2
    assert to_float(to_int_2(-1.03e-30) + to_int_2(-2.04e-31)) == (-1.234e-30)
    assert to_float(to_int_2(-1.03e+130) + to_int_2(-2.04e+129)) == (-1.234e+130)
    try:
        to_int_2(1e-300) == 0
    except AssertionError as e:
        assert str(e) == 'Not enough precision'
    try:
        print(to_int_2(1e+300))
    except OverflowError as e:
        assert str(e) == 'cannot convert Infinity to integer ratio'
    

    现在我得出的结论是不需要 as_integer_ratio,检查res == 0 and f != 0to_int 就足够了。

    • 1
  5. Zhihar
    2021-10-19T19:49:44Z2021-10-19T19:49:44Z

    第一种方式

    好在编程中没有无理数:),这意味着任何浮点数都是有理数

    因此,它可以表示为分数 - 即 2个号码int

    鉴于在python中整数值不限于long,那么一个数中可以有2个数

    例如0,5是[5][10],

    可以实现这样的存储

    第二种方式

    float很容易翻译成固定的数字——具有固定点的数字——例如,如果我们假设前 n 个字符是整数部分,而后 m 个字符是小数部分,那么

    数字的加法和减法将与 float 或 int 完全相同

    数字的比较将与 float 或 int 完全相同

    乘法会略有不同 -

    (a * b) >> m
    

    浮动到固定翻译:

    fixed_value = 2**m * float_value
    

    分别返回

    float_value = fixed_value / 2**m
    
    • 0
  6. Barmaley
    2021-10-19T20:27:59Z2021-10-19T20:27:59Z

    2种方法:

    出去float_long

    def floatToRawLongBits(f):
        s = struct.pack('=f', f)
        return struct.unpack('=l', s)[0]
    

    从long回到float

    def longToRawFloatBits(l):
        s = struct.pack('=l', l)
        return struct.unpack('=f', s)[0]
    

    在 Python 熟练之前,请不要重击、踢腿

    Java 有一个方法Float.floatToRawIntBits(),根据 IEEE 754 位定义,它表示整数的位。以此类推,有一个解决办法

    • 0

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5