防止Python中的浮点除法出现下溢 [英] Prevent underflow in floating point division in Python

查看:71
本文介绍了防止Python中的浮点除法出现下溢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设 x y 都是很小的数字,但是我知道 x/y 的真实值是合理的.

Suppose both x and y are very small numbers, but I know that the true value of x / y is reasonable.

计算 x/y 的最佳方法是什么?特别是,我一直在做 np.exp(np.log(x)-np.log(y),但我不确定这是否会有所作为?

What is the best way to compute x/y? In particular, I have been doing np.exp(np.log(x) - np.log(y) instead, but I'm not sure if that would make a difference at all?

推荐答案

根据

Python uses the floating-point features of the hardware it runs on, according to Python documentation. On most common machines today, that is IEEE-754 arithmetic or something near it. That Python documentation is not explicit about rounding mode but mentions in passing that the result of a sample division is the nearest representable value, so presumably Python uses round-to-nearest-ties-to-even mode. ("Round-to-nearest" for short. If two representable values are equally close in binary floating-point, the one with a zero in the low bit of its significand is produced.)

在最近舍入模式下的IEEE-754算术中,除法结果是最接近精确数学值的可表示值.因为您说 x/y 的数学值是合理的,所以它在可表示值的正常范围内(不在此范围内,在受到精度影响的次标准范围内,而在该范围内而不是在其上产生精度的范围内)舍入到无穷大).在正常范围内,基本运算的结果将在格式的正常精度范围内准确.

In IEEE-754 arithmetic in round-to-nearest mode, the result of a division is the representable value nearest to the exact mathematical value. Since you say the mathematical value of x/y is reasonable, it is in the normal range of representable values (not below it, in the subnormal range, where precision suffers, and not above it, where results are rounded to infinity). In the normal range, results of elementary operations will be accurate within the normal precision of the format.

但是,由于 x y 是非常小的数字",我们可能会担心它们是次正规的,并且在除法之前已经存在精度损失被执行.在IEEE-754基本64位二进制格式中,低于2 -1022 (约2.22507•10 -308 )的数字是次正规的.如果 x y 小于该值,则它们已经失去了精度,并且除非偶然,否则任何方法都无法从它们中产生正确的商.用对数计算商将无济于事.

However, since x and y are "very small numbers," we may be concerned that they are subnormal and have a loss of precision already in them, before division is performed. In the IEEE-754 basic 64-bit binary format, numbers below 2-1022 (about 2.22507•10-308) are subnormal. If x and y are smaller than that, then they have already suffered a loss of precision, and no method can produce a correct quotient from them except by happenstance. Taking the logarithms to calculate the quotient will not help.

如果您所运行的计算机恰好未使用IEEE-754,则直接计算 x/y 仍可能会比 np.exp(np.log(x)-np.log(y)).前者是单个操作,可以计算合理设计的硬件中的基本功能.后者是用软件计算复杂功能的几种操作,这些操作很难使用常见的硬件操作来精确实现.

If the machine you are running on happens not to be using IEEE-754, it is still likely that computing x/y directly will produce a better result than np.exp(np.log(x)-np.log(y)). The former is a single operation computing a basic function in hardware that was likely reasonably designed. The latter is several operations computing complicated functions in software that is difficult to make accurate using common hardware operations.

浮点运算存在很大的不安和不信任感.缺乏知识似乎导致人们对此感到恐惧.但是,这里应该理解的是,基本浮点运算的定义非常明确,并且在正常范围内是准确的.浮点计算的实际问题是由于在操作序列上累积舍入误差,复合误差的内在数学以及对结果的不正确期望而引起的.这意味着无需担心单个分区的准确性.相反,应该牢记浮点的整体用法.(如果您的问题提供了更多的背景信息,则可以更好地回答您的问题,阐明为什么这种划分很重要,如何从先前的数据中产生 x y ,以及总体目标是什么?是.

There is a fair amount of unease and distrust of floating-point operations. Lack of knowledge seems to lead to people being afraid of them. But what should be understood here is that elementary floating-point operations are very well defined and are accurate in normal ranges. The actual problems with floating-point computing arise from accumulating rounding errors over sequences of operations, from the inherent mathematics that compounds errors, and from incorrect expectations about results. What this means is that there is no need to worry about the accuracy of a single division. Rather, it is the overall use of floating-point that should be kept in mind. (Your question could be better answered if it presented more context, illuminating why this division is important, how x and y have been produced from prior data, and what the overall goal is.)

与IEEE-754的常见偏差是将次标准值刷新为零.如果您有一些 x 和一些 y 是非正规的,则某些实现可能会在对其执行操作之前将其刷新为零.但是,这在SIMD代码中比在普通标量编程中更常见.而且,如果发生这种情况,无论如何,都会阻止您评估 np.log(x) np.log(y),因为次标准值会刷新为零在那些.因此我们可以消除这种可能性.

A not uncommon deviation from IEEE-754 is to flush subnormal values to zero. If you have some x and some y that are subnormal, some implementations might flush them to zero before performing operations on them. However, this is more common in SIMD code than in normal scalar programming. And, if it were occurring, it would prevent you from evaluating np.log(x) and np.log(y) anyway, as subnormal values would be flushed to zero in those as well. So we can likely dismiss this possibility.

这篇关于防止Python中的浮点除法出现下溢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆