跳转到主要内容

找到给定浮点数或区间的最简分数

项目描述

simplefractions包可以找到将给定浮点数转换为最简分数,或者更普遍地说,找到给定区间内的最简分数。

定义。 给定分数 x = a/by = c/d(以最小公倍数和正分母的形式写出),如果 abs(a) <= abs(c)b <= d,并且至少有一个不等式是严格的,则说 xy 更简单。

例如,22/7比23/8更简单,但3/8和4/7都不是比对方更简单。

那么,这是一个定理:给定任何至少包含一个分数的实数子区间 I,该区间包含一个唯一的简单分数。也就是说,在 I 中存在一个分数 a/b,使得 a/b 比区间 I 中的所有其他分数都简单(在上述意义上)。因此,对于任何给定的有限Python浮点数 x,都有一个唯一的简单分数可以四舍五入到该浮点数。

simplefractions包提供两个函数

  • simplest_from_float返回,对于给定的浮点数 x,具有 float(simplest_from_float(x)) == x 属性的唯一最简分数。
  • simplest_in_interval返回给定(开或闭,有界或无界)非空区间内的唯一最简分数。

示例用法

首先从模块中导入函数

>>> from simplefractions import *

simplest_from_float 函数接受一个有限的浮点数 x,并生成一个 Fraction 对象,该对象可以恢复该浮点数

>>> simplest_from_float(0.25)
Fraction(1, 4)
>>> simplest_from_float(0.33)
Fraction(33, 100)

无论给定什么 x,不变量 float(simplest_from_float(x)) == x 总是成立的。

>>> x = 0.7429667872099244
>>> simplest_from_float(x)
Fraction(88650459, 119319545)
>>> float(simplest_from_float(x))
0.7429667872099244
>>> float(simplest_from_float(x)) == x
True

如果浮点数 x 是通过除以两个小的整数构造的,那么在大多数情况下,simplest_from_float 将恢复这些整数

>>> x = 231 / 199
>>> x
1.1608040201005025
>>> simplest_from_float(x)
Fraction(231, 199)

更精确地说,如果 x 是通过除以两个小于或等于 67114657(绝对值)的互质整数构造的,那么 simplest_from_float 将恢复这些整数。

>>> simplest_from_float(64841043 / 66055498)
Fraction(64841043, 66055498)

67114657 是我们在这里能做的最好的。

>>> simplest_from_float(67114658 / 67114657)
Fraction(67114657, 67114656)

在更大的情况下,simplest_from_float 可能会发现一个更简单的分数,该分数给出相同的浮点数

>>> x = 818421477165 / 1580973145504
>>> simplest_from_float(x)
Fraction(5171, 9989)
>>> 818421477165 / 1580973145504 == 5171 / 9989
True

请注意,simplest_from_float 并不能神奇地修复浮点数的精度误差。例如

>>> x = 1.1 + 2.2
>>> simplest_from_float(x)
Fraction(675539944105597, 204709073971393)

您可能期望在这里看到 Fraction(33, 10),但将其转换为浮点数时,得到的值非常接近,但不完全等于 x。相比之下,simplest_from_float(x) 的返回值在转换为 float 时总是产生完全等于 x 的值。

为了修复这个问题,您可能需要要求一个最简单的浮点数,它在 x 的某个小误差范围内,例如,在两个方向上都在 5 ulps(最后一位的单位)内。 simplest_from_float 无法做到这一点,但 simplest_in_interval 可以!例如

>>> from math import ulp
>>> x = 1.1 + 2.2
>>> simplest_in_interval(x - 5*ulp(x), x + 5*ulp(x))
Fraction(33, 10)

或者,您可能要求一个最简单的分数,它以最大的相对误差 0.000001 来逼近 x

>>> relerr = 1e-6
>>> simplest_in_interval(x - relerr*x, x + relerr*x)
Fraction(33, 10)

以下是 simplest_in_interval 的一些应用示例。 simplest_in_interval 的输入可以是浮点数、整数或 Fraction 对象。

>>> simplest_in_interval(3.14, 3.15)
Fraction(22, 7)

默认情况下,simplest_in_interval 假设您指定的是一个开区间

>>> simplest_in_interval(3, 4)
Fraction(7, 2)

关键字参数 include_leftinclude_right 允许您指定一个或两个端点应该包含在区间内

>>> simplest_in_interval(3, 4, include_left=True, include_right=True)
Fraction(3, 1)

区间的左端点和右端点都是可选的,允许指定半无限或无限区间

>>> simplest_in_interval(right=4)  # simplest in (-inf, 4)
Fraction(0, 1)
>>> simplest_in_interval(left=4, include_left=True)  # simplest in [4, inf)
Fraction(4, 1)
>>> simplest_in_interval()  # simplest in (-inf, inf)
Fraction(0, 1)

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源代码分发

simplefractions-1.2.1.tar.gz (288.0 kB 查看哈希值)

上传时间 源代码

构建分发

simplefractions-1.2.1-py3-none-any.whl (14.5 kB 查看哈希值)

上传时间 Python 3

支持者

AWSAWS云计算和安全赞助商DatadogDatadog监控FastlyFastlyCDNGoogleGoogle下载分析MicrosoftMicrosoftPSF赞助商PingdomPingdom监控SentrySentry错误日志StatusPageStatusPage状态页面