我试图识别大量的立方根。我找到了一个解决方案,适用于较小的数字,但不是在这种情况下:
require 'openssl'
q = OpenSSL::BN::generate_prime(2048)
ti = q.to_i #=> 3202718747...
ti3 = ti ** 3 #=> 328515909...
m = ti3 ** (1/3.0) #=> Infinity
我希望看到m
= ti
的原始输出。是的,这是Matasano挑战的一部分。到目前为止,我已经花了很多精力去寻求帮助,但是我已经达到了这样一个地步:#我该如何做一些简单的事情,在Ruby&#34 ;。任何帮助表示赞赏。
答案 0 :(得分:1)
在整数的ruby操作中,自动升级为bignums(任意精度整数),因此永远不会出现溢出。
浮点运算也是如此:你最终得到无穷大,因为提升到1/3的幂是一个浮点运算,它做的第一件事是尝试将你的数字转换为浮点运算。红宝石中浮动的最大数字可以代表大约10 ^ 308,而你的数字可能大约是10 ^ 1800大关,所以它拯救并返回无限
Ruby有一个BigDecimal
类。因此你可能想要做
BigDecimal.new(ti3) ** (1/3.0)
这给了我一个非常错误的答案 - 我怀疑因为(1 / 3.0)是一个浮点数,所以只有大约1/3
BigDecimal.new(ti3) ** Rational(1,3)
另一方面为我产生正确的结果(误差可以忽略不计)。 Rational
是Ruby用于以精确方式表示分数的类。在ruby 2.1中,您可以将其缩短为
BigDecimal.new(ti3) ** (1r/3)
文档确实说只支持整数指数,但这似乎是红宝石1.8天的宿醉
答案 1 :(得分:0)
我不知道Matasano的挑战是什么,但我想到的是Newton's Method
Cube Roots上的维基百科页面也建议使用牛顿法
答案 2 :(得分:0)
根据给出的两条建议提出以下代码。
def nthroot(n, a, precision = 1e-1024)
x = a
begin
prev = x
x = ((n - 1) * prev + a / (prev ** (n - 1))) / n
end while (prev - x).abs > precision
x
end
它基于牛顿方法的实现,它处理浮点数,但也只是返回无穷大。此版本仅处理整数,但适用于大整数。
当然,可以用n = 3来调用nthroot。