Ruby 我如何在不使用乘法的情况下求一个数的平方?
我想知道是否有一种方法可以编写一个不使用运算符号(Ruby 我如何在不使用乘法的情况下求一个数的平方?,ruby,algorithm,numbers,perfect-square,Ruby,Algorithm,Numbers,Perfect Square,我想知道是否有一种方法可以编写一个不使用运算符号(*)的数字平方(整数或十进制/浮点)。例如:2的平方将是4,2.5的平方将是6.25,3.5的平方将是12.25 我的做法如下: def square(num) number = num number2 = number (1...(number2.floor)).each{ num += number } num end puts square(2) #=> 4 [Correct] puts square(16) #=&
*
)的数字平方(整数或十进制/浮点)。例如:2
的平方将是4
,2.5
的平方将是6.25
,3.5
的平方将是12.25
我的做法如下:
def square(num)
number = num
number2 = number
(1...(number2.floor)).each{ num += number }
num
end
puts square(2) #=> 4 [Correct]
puts square(16) #=> 256 [Correct]
puts square(2.5) #=> 5.0 [Wrong]
puts square(3.5) #=> 10.5 [Wrong]
该代码适用于整数,但不适用于浮点数/小数。我做错了什么?此外,如果有人有一个新的方法来解决这个问题,那么请分享。算法也是受欢迎的。此外,考虑到该方法的性能将是一个加号。好吧,乘法的逆是除法,所以你可以通过除以它的逆得到相同的结果*。也就是说:
square(n)=n/(1.0/n)
。只需确保您不会无意中进行整数除法
*从技术上讲,两次除法在浮点运算中引入了第二个舍入错误的机会,因为它执行两次运算。因此,这不会产生与浮点乘法完全相同的结果-但这也不是问题的要求。好的,乘法的逆是除法,所以你可以通过除以它的逆得到相同的结果*。也就是说:
square(n)=n/(1.0/n)
。只需确保您不会无意中进行整数除法
*从技术上讲,两次除法在浮点运算中引入了第二个舍入错误的机会,因为它执行两次运算。因此,这将不会产生与浮点乘法完全相同的结果-但这也不是问题的要求。您可以使用一些技巧,按增加技巧的顺序排列在这里 对数 观察
k*k=e^log(k*k)=e^(log(k)+log(k))
,并使用该规则:
Math.exp(Math.log(5.2)+Math.log(5.2))
# => 27.04
这里没有乘法运算
分部
正如另一位评论者所建议的,您可以采用相反的操作,除法:k/(1.0/k)==k^2
。但是,这会引入额外的浮点错误,因为k/(1.0/k)
是两个浮点操作,而k*k
只是一个
指数化
或者,由于这是Ruby,如果您想要与浮点运算完全相同的值,而不想使用乘法运算符,则可以使用求幂运算符:k**2==k*k
调用web服务
如果你自己不做,它就不会成倍增长
require 'wolfram' # https://github.com/cldwalker/wolfram
query = 'Square[5.2]'
result = Wolfram.fetch(query)
明目张胆的欺骗
最后,如果您觉得非常便宜,您可以避免实际使用文本“*”操作,并使用等效的操作:
n = ...
require 'base64'
n.send (Base64.decode64 'Kg==').to_sym, n # => n * n
你可以使用一些技巧,按照增加技巧的顺序排列在这里 对数 观察
k*k=e^log(k*k)=e^(log(k)+log(k))
,并使用该规则:
Math.exp(Math.log(5.2)+Math.log(5.2))
# => 27.04
这里没有乘法运算
分部
正如另一位评论者所建议的,您可以采用相反的操作,除法:k/(1.0/k)==k^2
。但是,这会引入额外的浮点错误,因为k/(1.0/k)
是两个浮点操作,而k*k
只是一个
指数化
或者,由于这是Ruby,如果您想要与浮点运算完全相同的值,而不想使用乘法运算符,则可以使用求幂运算符:k**2==k*k
调用web服务
如果你自己不做,它就不会成倍增长
require 'wolfram' # https://github.com/cldwalker/wolfram
query = 'Square[5.2]'
result = Wolfram.fetch(query)
明目张胆的欺骗
最后,如果您觉得非常便宜,您可以避免实际使用文本“*”操作,并使用等效的操作:
n = ...
require 'base64'
n.send (Base64.decode64 'Kg==').to_sym, n # => n * n
没有使用任何操作标志
def square(num)
num.send 42.chr, num
end
没有使用任何操作标志
def square(num)
num.send 42.chr, num
end
2.5
到5.0
。。这是正确的吗?怎么了?糟糕,现在是6点25分。感谢您收听:)2.5
至5.0
。。这是正确的吗?怎么了?糟糕,现在是6点25分。感谢您捕捉:)这并不等同于浮点乘法。您进行了两次除法并累积了2个错误(1/n
,n/(1/n)
),而不是1个错误(n*n
)。如果您定义defs(n);n/(1.0/n)
,您将得到s(5.1)==26.009…994
和5.1**2==26.009…998
,这两个值不是相等的。@JohnFeminella有效点,但是OP没有指定这是一个要求确保,但是如果不要求“精确答案”,那么任何答案都是正确的,甚至是错误的。那么,问题就在于错误有多大程度上是可以接受的@约翰菲米内拉说得很对,这一点很好。尽管使用浮点运算,您最终不会得到“精确答案”,是吗?:)然后问题会回到为什么OP首先要避开*
操作符。当我尝试(1/n
,n/(1/n)
)时,它引发了零错误。因此,它必须(
1.0/n,
n/(1.0/n))
因此,它采用十进制数而不是整数。接得好。:)这并不等同于浮点乘法。您进行了两次除法并累积了2个错误(1/n
,n/(1/n)
),而不是1个错误(n*n
)。如果您定义defs(n);n/(1.0/n)
,您将得到s(5.1)==26.009…994
和5.1**2==26.009…998
,这两个值不是相等的。@JohnFeminella有效点,但是OP没有指定这是一个要求确保,但是如果不要求“精确答案”,那么任何答案都是正确的,甚至是错误的。那么,问题就在于错误有多大程度上是可以接受的@约翰菲米内拉说得很对,这一点很好。尽管使用浮点运算,您最终不会得到“精确答案”,是吗?:)然后问题会回到OP为什么要避免*