【问题标题】:Generate and check the primality of very large numbers in Livecode在 Livecode 中生成并检查非常大数的素数
【发布时间】:2017-04-25 01:44:19
【问题描述】:

我该怎么做?这些产生语言的所有其他结果不是 LiveCode 或由于某种原因在 LiveCode 中不起作用。数字必须随机生成;否则,我可以从here 中取一些(是的,~150 位数)。最终目标是将这些用于加密(个人实验)。

【问题讨论】:

    标签: random primes livecode


    【解决方案1】:

    你没有说到目前为止你做了什么。生成大素数的基本方法是:

    repeat
      pick a large possible prime
    until (the number you picked is prime)
    

    那是伪代码,因为我不知道 LiveCode。您必须自己进行转换。

    所有大素数的形式为 6n ± 1。您可以根据所需的素数大小在合适的范围内选择 n。

    对于素数测试,您必须将标准素数测试之一转换为 LiveCode。或者,有没有办法将其他语言的外部方法合并到 LiveCode 中,这样您就可以从网络上复制一个示例?

    【讨论】:

      【解决方案2】:

      我们在这里谈论多大?大多数编程语言都使用标准数字类型在内部存储数字,这些数字具有固定大小(例如,4 个字节为您提供大约 -20 亿到 +20 亿之间的数字)。

      因此他们不太可能处理 150 位数字。

      您可能必须获得一个 LiveCode 插件(外部?无论 LiveCode 使用什么来称呼它们),它可以处理非常大的数字或执行“字符串数学”。

      【讨论】:

        【解决方案3】:

        LiveCode 使用列表的 Devin Asay 先生提供了这个:

        on mouseUp
         local tNum
         put fld 2 into tNum
         put "" into fld 1
         put isPrime(tNum) into fld 1
        end mouseUp
        
        function isPrime pNum
         if pNum <> 2 AND pNum mod 2 = 0 then
          return false
         end if
         repeat with x = 3 to sqrt(pNum) step 2
          if pNum mod x = 0 then
             return false
          end if
         end repeat
         return true
        end isPrime
        

        由于范围(溢出)错误,处理程序在 309 位时失败。这是机器限制,而不是 LC 限制。处理程序的整体精度是有限的(LC 团队的 Mark Waddingham 表示):

        您只能表示最大为 2^53 左右的整数而不会丢失 精度(因为它们使用 IEEE 双精度表示),这意味着 您可以使用此方法检查素数的最大数量约为 9007199254740992。

        【讨论】:

          【解决方案4】:

          我可以毫无问题地处理使用 livecode 或任何其他语言的数字 long 任何数字的完全完美。我可以只使用 + - / * 操作,但我认为这对你的研究来说已经足够了。我做了这个函数:

          function bigAdd a1, a2
            #let's check if it's negative...
            #end check
            put reverse2(a1) into b1
            put reverse2(a2) into b2
            put 0 into mem
            if length(b1) < length(b2) then
              put b1 into temp
              put b2 into b1
              put temp into b1
            end if
            repeat while b2 is not empty
              put (char 1 of b1) + (char 1 of b2) + mem into ppp
              if length(ppp) = 1 then
                 put 0 into mem
                 put ppp before rrr
             else
               put 1 into mem
               put char 2 of ppp before rrr
             end if
            delete char 1 of b1
            delete char 1 of b2
          end repeat
          repeat while (b1 is not empty)
          put mem + (char 1 of b1) into ppp
          if length(ppp) = 1 then
          put 0 into mem
          put ppp before rrr
          else
          put 1 into mem
          put char 2 of ppp before rrr
          end if
          delete char 1 of b1
          end repeat
          if mem = 1 then
          put 1 before rrr
          else
          put b1 before rrr
          end if
          return rrr
          end bigAdd
          
          function reverse2 temp
          repeat for each char tChar in temp
          put tChar before temp2
          end repeat
          return temp2
          end reverse2
          
          
          function bigMultiply a1,a2
          put reverse2(a1) into a1
          put 0 into temp
          repeat for each char tChar in a1
          repeat with i=1 to tChar
          put bigAdd(temp,a2) into temp
          end repeat
          put 0 after a2
          end repeat
          return temp
          end bigMultiply
          
          function bigGreater a1,a2
          #compare two bignumbers:
          #return true if n1 > n2
          #return false if n1 < n2
          #return empty if n1 = n2
          #let's check is a number is negative
          if ((char 1 of a1 = "-") or (char 1 of a2 = "-")) then
          if ((char 1 of a1 = "-") and (char 1 of a2 is not "-")) then
          return false
          end if
          if ((char 1 of a1 is not "-") and ( char 1 of a2 = "-" )) then
          return true
          end if
          #if we are here, both are negative
          delete char 1 of a1
          delete char 1 of a2
          if a1 = a2 then
          return empty
          else
          return (not bigGreater(a1,a2))
          end if
          end if
          if length(a1) is not length(a2) then
          return ( length(a1) > length(a2) ) #this is evalueted true or false
          else
          if a1 = a2 then
          return empty
          else
          repeat while ((char 1 of a1) = (char 1 of a2) )
          delete char 1 of a1
          delete char 1 of a2
          end repeat
          return ((char 1 of a1) > (char 1 of a2)) #this is evalueted true or false
          end if
          end if
          end bigGreater
          
          function bigSub a1,a2
          #substract the smallest big number from the largest one
          if bigGreater(a2,a1) then
          put a1 into temp
          put a2 into a1
          put temp into a2
          end if
          put reverse2(a1) into a1
          put reverse2(a2) into a2
          put 0 into mem
          repeat while (a2 is not empty)
          put (char 1 of a1) - mem + 10 - (char 1 of a2) into minus
          if length(minus) = 1 then
          put 1 into mem
          put minus before rrr
          else
          put 0 into mem
          put char 2 of minus before rrr
          end if
          delete char 1 of a1
          delete char 1 of a2
          end repeat
          repeat while (a1 is not empty)
          put char 1 of a1 + 10 - mem into minus
          if length(minus) = 1 then
          put 1 into mem
          put minus before rrr
          else
          put 0 into mem
          put char 2 of minus before rrr
          end if
          delete char 1 of a1
          end repeat
          #remove inital zeros
          repeat while (char 1 of rrr is "0")
          delete char 1 of rrr
          end repeat
          return rrr
          end bigSub
          
          function bigDivide a1,a2
          #output is a block of two numbers "quotient , remainder"
          if bigGreater(a2,a1) then
          return ("0," & a1)
          end if
          if a1 = a2 then
          return "1,0"
          end if
          put 0 into count
          repeat while (bigGreater(a1,a2))
          put bigSub(a1,a2) into a1
          put bigAdd(1,count) into count
          end repeat
          if a1 = a2 then
          put bigAdd(count,1) into count
          put 0 into a1
          end if
          return (count & comma & a1)
          end bigDivide
          
          function bigDivide2 a1,a2
          #please note that the result is "the result, the remainder"
          put length(a1) into ldividendo
          put length(a2) into ldivisore
          if ldividendo <= ldivisore then
          return bigDivide(a1,a2)
          end if
          put char 1 to ldivisore of a1 into tDiv
          put bigDivide(tDiv,a2) into rrr
          put item 1 of rrr into quoziente
          put item 2 of rrr into resto
          put ldivisore + 1 into nn
          repeat with i = nn to ldividendo
          put char i of a1 after resto
          put bigDivide(resto,a2) into temp
          put item 1 of temp after quoziente
          put item 2 of temp into resto
          end repeat
          put removezeros(quoziente) into quoziente
          put removezeros(resto) into resto
          return (quoziente & comma & resto)
          end bigDivide2
          
          function removezeros temp
          repeat while char 1 of temp is "0"
          delete char 1 of temp
          end repeat
          return temp
          end removezeros
          

          【讨论】:

            猜你喜欢
            • 2010-11-11
            • 1970-01-01
            • 1970-01-01
            • 2011-07-23
            • 1970-01-01
            • 2012-10-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多