大数的最后一位数(Ruby)如何处理NaN?

时间:2017-07-26 21:06:34

标签: ruby math

这是我的代码:

def last_digit(n1, n2)
array = (n1.to_i ** n2.to_i).to_s.split("")
array[-1].to_i
end

TEST:(2 ^ 200)^(2 ^ 300)的最后一位十进制数,超过10 ^ 92位十进制数,为6

我试图返回最后一个数字的最后一位数字,我确定这是正确的但是当我运行测试时2返回失败。

我认为由于数字太大,我怎么能让这段代码保持准确无论它有多大。

另外,我如何处理NaN,我已经搜索并努力寻找有用的东西。

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

有一种有效的算法,它假定只有一个数字的最后一个数字才有效。请尝试一下您的测试,并随时纠正此实现中的任何缺陷,您可以通过运行它们找到它们

def digit_of_power(digit, n)
  digit = digit % 10

  case digit
  when 0, 1, 5, 6 then digit
  else
    digit_of_square = digit * digit

    if n.even?
      digit_of_power(digit_of_square, n / 2)
    else
      digit * digit_of_power(digit_of_square, (n - 1) / 2) % 10
    end
  end
end

答案 1 :(得分:1)

这是我的解决方案

def last_digit(n1, n2)
  return 1 if n2 == 0
  return 0 if n1 == 0
  exp = (n2 % 4 == 0) ? 4 : n2 % 4
  return (n1**exp) % 10
end

您可能希望阅读本文(finding the last digit of a power),以获得有关此数学问题解决方案的更详细说明。

看一下下表:

enter image description here

您可以看到循环重复的最大长度为4。

例如:

  • 2 * 2 = 4
  • 4 * 2 = 8
  • 8 * 2 = 16
  • 16 * 2 = 32
  • 32 * 2 = 64
  • 64 * 2 = 128
  • 128 * 2 = 256
  • 256 * 2 = 512

32中的最后一位是2(因为它在512中),这意味着在将数字乘以4后,它将重复出现。

该算法遵循以下逻辑:

你减少指数,知道如果它可以被4整除,它的新值是4,因为将它乘以4会得到根据上表的最后一位数。否则,其值 n2%4

作为最后一步,您执行此操作 n1 ^ exp%10 ,因为您只需要最后一个数字。

注意:

我成功测试了大量数据。

  • n1 = 38710248912497124917933333333284108412048102948908149081409204712406
  • n2 = 226628148126342643123641923461846128214626

顺便说一句,我意识到我迟到了回答你的问题。我认为有一天它可能对其他人有帮助。

答案 2 :(得分:0)

<强>代码

ENDINGS = [[0,0,0,0], [1,1,1,1], [2,4,8,6], [3,9,7,1], [4,6,4,6],    
           [5,5,5,5], [6,6,6,6], [7,9,3,1], [8,4,2,6], [9,1,9,1]]

def last_digit_of_power(digit, power)
  return 1 if power.zero?
  ENDINGS[digit][(power-1) % 4]
end

<强>实施例

让我们尝试power等于5然后6

(5..6).each do |power|
  puts "\npow = #{power}"
  (0..9).each {|digit| puts "#{digit}: #{last_digit_of_power(digit, power)}"}
end

pow = 5
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9

pow = 6
0: 0
1: 1
2: 4
3: 9
4: 6
5: 5
6: 6
7: 9
8: 4
9: 1

<强>解释

这使用与@Igor相同的算法,但我实现的方式不同。已知(并且可以容易地证明)每个数字0-9的最后一个数字被用于增加的功率在最多4个数字之间循环。例如,考虑数字3。由于

[1,2,3,4,5].map { |power| 3**power } 
  #=> [3, 9, 27, 81, 243]

3每个5次幂的[3, 9, 7, 1, 3]的最后一位是3**5。由于3**1的最后一位数字与3**6的最后一位数字相同,我们推断3**(6-4)的最后一位数字与3**2的最后一位数字相同(9),即3**15,依此类推。

现在假设我们希望计算3**(15-4)的最后一位数字。我们看到它与3**113**7)的最后一位相同,后者又等于3**3的最后一位数,然后是最后一位7 ,但我们已经知道了最后一个,3**power。因此,[3, 9, 7, 1][(power-1) % 4] 的最后一位是

ENDINGS

1-4为每个数字0-9提供了1次幂的最后数字。请注意,0156的周期长度为24和{{9的周期长度为4 1}} 2 378410。但是,对所有ENDINGS[digit]数字使用digit的周期长度是最方便的。

1等于2取得34digitpower权力的四个结局。因此,数字ENDINGS[digit][(power-1) % 4] 取代幂<asp:ObjectDataSource ID="ods1" runat="server" EnablePaging="True" OldValuesParameterFormatString="original_{0}" SelectCountMethod="GetProductsCount" SelectMethod="GetProductsByPageSort" TypeName="ExpressSelect.ProductData" DataObjectTypeName="ExpressSelect.SearchProduct"> <SelectParameters> <asp:QueryStringParameter DefaultValue="0" Name="startRowIndex" QueryStringField="sri" Type="Int32" /> <asp:QueryStringParameter DefaultValue="10" Name="maximumRows" QueryStringField="rows" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource> 的最后一位数等于

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    Dim sri As String = Request.QueryString("sri")
    Dim rows As String = Request.QueryString("rows")
End Sub