tuple
它们都是两个s的全部,它们代表(几乎)无限精度(仅由计算机存储器界定),第一个数字是分子,第二个分母。
如果我们将它们分开,我们得到了π的第一个十进制位置:(601550405185810455248373798733610900689885946410558295383908863020551447581889414152035914344864580636662293641050147614154610394724089543305418716041082523503171641011728703744273399267895810412812627682686305964507416778143771218949050158028407021152173879713433156038667304976240165476457605035649956901133077856035193743615197184,
191479441008508487760634222418439911957601682008868450843945373670464368694409556412664937174591858285324642229867265839916055393493144203677491629737464170928066273172154431360491037381070068776978301192672069310596051608957593418323738306558817176090035871566224143565145070495468977426925354101694409791889484040439128875732421875)
我使用整数数学,而无需使用任何库来完成所有操作。我没有使用任何浮点,因为我知道它们都是有限的精度,而
tuple
python中的无限精度。Python's使用this
,它只有log
10(2) * 52 = 15.653559774527022小数点,远小于我想要的。我写了两个正确的功能,以获取任何分数的N指定的小数点:
int
他们的工作,但两者都效率低下,因为他们实际上做了很长的分裂。
它们都遵守以下规则:
它们应返回分数扩展到所需的宽度,除非分数在达到宽度之前终止(我们在达到宽度之前有一个确切的有限十进制表示); 如果十进制膨胀截止的最后几位数字为0,在这种情况下,除非第一个小数位数为0,否则结果不应包含任何尾随的零。 additiondition,第二个函数一旦具有一个周期的所有数字,就会脱离循环,并通过重复循环构建剩余的数字,尽管在每次迭代中都会完成更多的工作,因此,如果循环短,则速度更快,并且如果周期更长,则较慢。最糟糕的情况是,如果周期长于'3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798'
,因此它可以完成所有额外的工作,而无需尽早终止:
int
我们如何做得比长期分裂更好,以便大幅度减少执行时间,同时实现相同的结果(使用整数数学来获得无限的精度表示分数)?最好是在不使用任何图书馆的情况下完成此操作,因为我想知道算法。
确实,整数工作更精确,因此,关键是使用整数除法以及缩放来计算所有数字,包括小数点后的数字。 然后将小数点放在正确的位置。 因此该功能看起来像:
float
from typing import Dict, List, Tuple
def decimalize(dividend: int, divisor: int, places: int) -> str:
div, mod = divmod(dividend, divisor)
result = [f"{div}."]
while mod and places:
div, mod = divmod(mod * 10, divisor)
result.append(str(div))
places -= 1
integral, first, *others = result
return integral + first + "".join(others).rstrip("0")
def pad_cycles(mod: int, places: int, pairs: Dict[int, str], result: List[str]) -> None:
if mod and places:
i = list(pairs).index(mod)
cycle = "".join(list(pairs.values())[i:])
div, mod = divmod(places, len(cycle))
result.append(cycle * div + cycle[:mod])
def decimalize1(dividend: int, divisor: int, places: int) -> str:
div, mod = divmod(dividend, divisor)
result = [f"{div}."]
pairs = {}
while mod and places and mod not in pairs:
div, mod1 = divmod(mod * 10, divisor)
pairs[mod] = (div := str(div))
result.append(div)
mod = mod1
places -= 1
pad_cycles(mod, places, pairs, result)
integral, first, *others = result
return integral + first + "".join(others).rstrip("0")