Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python为什么以及如何截断数字数据?_Python_Serialization_Floating Accuracy - Fatal编程技术网

python为什么以及如何截断数字数据?

python为什么以及如何截断数字数据?,python,serialization,floating-accuracy,Python,Serialization,Floating Accuracy,我在这里处理两个变量,但很困惑,因为当我想将它们作为URL参数发送时,它们的值似乎在改变(它们失去了精度) 当我在这里从python解释器复制它时,看看这个场景: >>> lat = 0.33245794180134 >>> long = 32.57355093956 >>> lat 0.33245794180133997 >>> long 32.57355093956 >>> nl = str(lat)

我在这里处理两个变量,但很困惑,因为当我想将它们作为URL参数发送时,它们的值似乎在改变(它们失去了精度)

当我在这里从python解释器复制它时,看看这个场景:

>>> lat = 0.33245794180134
>>> long = 32.57355093956
>>> lat
0.33245794180133997
>>> long
32.57355093956
>>> nl = str(lat)
>>> nl '0.332457941801'
>>> nlo = str(long)
>>> nlo '32.5735509396'
那么发生了什么?当我将
lat
long
序列化为字符串并将它们作为url查询字符串的一部分发送时,如何确保不会丢失它们的精确性

为澄清情况:

  • 数据最初以浮点形式(在集合中)从另一个通过计算创建它们的模块传入我的模块
  • 精度在这里是一个敏感的问题,因为这些数据被用于跟踪和监视排序,错误的值可能会导致误报或不必要的报警
  • 如果不将数据序列化为字符串,就无法将数据发送到目标引擎(通过restiful api进行侦听)(因此我可以将它们作为参数放在查询字符串中)

  • 因此,我需要的是以最小的精度/信息损失将浮点转换为字符串的最佳方法。

    您可以尝试使用字符串格式来获得所需的精度

    >>> lat = 0.33245794180134
    >>> lat
    0.33245794180134
    >>> "%.14f" % lat
    '0.33245794180134'
    >>> 
    
    编辑以合并评论:

    >>> '{0:.14f}'.format(lat)
    '0.33245794180134'
    >>> 
    

    str
    用于人类可读的表示。它很少产生与产生提供给它的值的表达式等价或相似的内容<另一方面,code>repr则明确表示了这一点。事实上,它是REPL用来反馈表达式结果的


    请注意,尽管浮点仍然是有限精度的,并且不能准确地表示某些数字,无论您如何将它们序列化为字符串。

    通常,如果您使用
    '%.14f'%lat
    ,您将失去精度

    要从浮点中获得完全精度,请使用
    repr()

    例如:

    >>> lat = 1/3.
    >>> lat
    0.3333333333333333
    >>> str(lat).count('3')
    12
    >>> ('%.14f' % lat).count('3')
    14
    >>> repr(lat).count('3')
    16
    >>>
    
    顺便说一句,您正在使用一个旧的Python

    >>> 0.33245794180134 == 0.33245794180133997
    True
    >>>
    
    Pythons 2.7之前的版本通过使用17位有效的十进制数字生成
    repr(a_float)
    ,因为这将保证
    float(repr(a_float))==a_float
    。新方法是使用提供相同保证的最小位数。按Ctrl-F键搜索
    repr()

    如果您是从外部源获取这些数字,那么您可能会因为将它们浮点化,然后使用14位小数精度对它们进行序列化而丢失精度

    >>> lat = 0.33245794180134
    >>> lat
    0.33245794180134
    >>> "%.14f" % lat
    '0.33245794180134'
    >>> 
    
    如果你是通过计算得到这些数字的,那么你可能会因为用14位小数的精度对它们进行序列化而失去精度

    >>> lat = 0.33245794180134
    >>> lat
    0.33245794180134
    >>> "%.14f" % lat
    '0.33245794180134'
    >>> 
    

    摘要:一般来说,如果使用“%.14f”%lat,您将丢失精度—不是Python,不是浮点算术,而是您。

    Python标准库十进制模块中的十进制类型肯定是您想要的。默认情况下,它允许您保持28位精度,但不会强制将数字转换为二进制浮点表示形式。十进制类型还允许涉及其他类型的数字的数学运算,而无需转换

    您的示例已转换为十进制:

    >>> import decimal
    >>> lat = decimal.Decimal(repr(0.33245794180134))
    >>> long = decimal.Decimal(repr(32.57355093956))
    >>> lat
    Decimal('0.33245794180134')
    >>> long
    Decimal('32.57355093956')
    >>> repr(lat)
    '0.33245794180134'
    >>> repr(long)
    '32.57355093956'
    
    将数字添加到十进制:

    >>> lat + 2
    Decimal('2.33245794180134')
    
    避免数字的二进制浮点表示的不精确性,如1.1:

    >>> onepointone = decimal.Decimal(repr(1.1))
    >>> onepointone
    Decimal('1.1')
    

    python标准库中的decimal模块是一个真正的数学模块,而不是传统浮点表示和浮点处理器的近似数学。我希望它是默认值,因为在字典中,我们在大多数语言中默认得到的近似浮点数学应该是无用定义的第一个示例。

    >>repr(0.33245794180134)
    给出了
    '0.33245794180133997'
    。因此,我仍然无法保留最初的数字!尽管
    repr
    肯定比
    str
    @mcnemesis好:这属于“浮动不准确”定律。请注意,即使您发送了一个正好表示这个数字的字符串,web服务也可能会将其转换为浮点,并失去保存的精度。还要注意的是,差异是3e-17=0.00000000000000003,因此它可能无论如何都不重要。感谢“法律”,但我必须满足规范,这些值代表的地理位置精度损失,有时会受到处罚。不管怎样,这些提示是好的。@mcnemesis:赤道大约有40000000000毫米长。这大约是11个有效数字。如果你需要超过12个有效数字,你必须有一个非常有趣的应用程序。“精度”的损失更可能是由于使用了不适当的公式造成的。John很好地演示了为什么
    repr
    更好。只有当要求说
    0.3334
    不应等于
    0.3333
    时,事情才会变得紧张起来。但我现在明白你的意思了。你为什么不使用
    format()
    ?如果你编辑你的问题,告诉我们(1)你是如何获得原始浮点值的(2)你为什么认为例如
    '0.33245794180134'
    是最佳或所需的输出值(3)你的“规格”实际上说了什么(4)什么“有时给出惩罚的精度损失”意味着。放弃“十进制”业务。这没有什么帮助。另外,
    {0:.14f}。格式(lat)
    工作得很好。@s.Lott:这是一个非常简单而且确实很好的方法。这是我在这个问题上采用的方法。我已经测试了
    '.14f'
    '{0:.14f}.格式(lat) >它们是非常好的和简单的!感谢这真的令人信服,尽管我的<代码> Python版本显示了<代码> Python 2.65。很好,你已经在我的首选方法上演示了<代码> RePr>代码>的一个很好的论证。我下次会考虑这个问题。是的,我现在真的开始接受这个更好的路径。因为目前,我的数据已经是浮点形式,这保留了(而且似乎提高了?)精度