【问题标题】:Simple multiplication and division being wildly inaccurate简单的乘法和除法非常不准确
【发布时间】:2020-04-13 22:39:02
【问题描述】:

tldr:公式 x / (1 * 1) 减去数百万亿。为什么?

大家好!我对python很陌生,在从头开始制作python消息加密器时,(我知道,有更简单的方法可以制作消息编码器。我只是为了体验和乐趣而制作它)非常简单的乘法和除法问题似乎非常不准确.基本上,我的编码器通过将输入字符串中的所有字符转换为数字,然后将数字乘以两个单独的用户提供的键来工作。我一直在将所有键设置为 1 进行测试,并且编码工作正常;解码是问题。我的公式是:

编码:

String = String * Key1 * Key2     #Both keys are set to 1

解码:

String = String / (Key1 * Key2)     #Again, both keys are set to 1, so in theory it should just spit the string back out.

当我输入 370190160220170180330190140310320 时,我得到 370190160220170177391212613337088

370190160220170180330190140310320

370190160220170177391212613337088

因此,等效于 x / (1 * 1) 的公式显然意味着减去多少万亿。这里发生了什么?就像我说的,我是 python 的新手,所以这个问题的解决方案可能非常简单,但我就是想不通。

【问题讨论】:

  • / 是浮点数,浮点数精度有限。

标签: python encoding division multiplication decoding


【解决方案1】:

float 除法 (/) 不是任意精确的。但是int除法(//)是!

试试这个:

assert 370190160220170180330190140310320 == 370190160220170180330190140310320 // 1
assert 370190160220170180330190140310320 != 370190160220170180330190140310320 / 1

对于您正在做的事情,您可能希望使用//% 而不是/

【讨论】:

    【解决方案2】:

    您需要使用Decimal 来准确拟合更大的数字,并且您需要将精度更改为大于默认值 28。

    from decimal import Decimal
    x = Decimal(370190160220170180330190140310320)
    print(x == (x/(1*1))) # False
    
    from decimal import Decimal, getcontext
    getcontext().prec = 40
    x = Decimal(370190160220170180330190140310320)
    print(x == (x/(1*1))) # True
    

    【讨论】:

    • 显然有人认为这是错误的,我很想学习 - 有什么问题?
    • Decimal 是错误的整数运算工具。它比普通整数慢,很容易搞砸精度,而且即使Decimal 仍然是浮点数,它也会给人一种误导的印象,即您使用的是精确类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 2023-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-26
    • 2017-07-28
    相关资源
    最近更新 更多