【问题标题】:How can I do mod without a mod operator?没有 mod 运算符我怎么能做 mod?
【发布时间】:2011-02-15 06:14:30
【问题描述】:

此脚本语言没有 % 或 Mod()。我确实有一个 Fix() 可以去掉数字的小数部分。我只需要积极的结果,所以不要太健壮。

【问题讨论】:

  • 您能否提及并标记您正在谈论的“愚蠢”脚本语言?
  • 我认为这是一种愚蠢的语言,叫做“作业”
  • 嘿。这是 Roku 数字标牌视频播放器上的一些嵌入式语言。它可能在某个地方确实有一个 Mod,但我肯定找不到它,而且它有 Arctan() 和 NaturalLog(),所以我真的很困惑他们是如何跳过 Mod 的。
  • 3.0 之前的glsl 也缺少整数模

标签: modulo roku brightscript


【解决方案1】:

// mod = a % b

c = Fix(a / b)
mod = a - b * c

做吗?我假设你至少可以在这里划分。所有的赌注都是负数。

【讨论】:

  • 根据你想要的负数,它可以调整。 fix() 总是截断,int() 总是向下舍入 (int(-2.5)=-3)
【解决方案2】:

这在性能方面可能对您不起作用,但是:

while (num >= mod_limit)
    num = num - mod_limit

【讨论】:

  • @tloflin,希望你不介意,但它应该是 ">=" 而不是 ">"。
  • 在性能方面不工作,你的意思是当 num 大约是 2**63 并且 mod_limit 是 3 时?
【解决方案3】:

a mod n = a - (n * Fix(a/n))

【讨论】:

    【解决方案4】:

    是什么语言?

    一个基本的算法可能是:

    hold the modulo in a variable (modulo);
    hold the target number in a variable (target);
    initialize modulus variable;
    
    while (target > 0) {
      if (target > modulo) {
        target -= modulo;
      }
      else if(target < modulo) {
        modulus = target;
        break;
      }
    }
    

    【讨论】:

    • 我认为target==modulo的情况有错误。无限循环。
    【解决方案5】:

    对于后代,BrightScript 现在有一个模运算符,它看起来像这样:

    c = a mod b
    

    【讨论】:

    • 这没有提供问题的答案。
    • @MDXF - 它没有提供问题 title 的答案,但实质上的答案是:如果您阅读正文,它会说“这种愚蠢的脚本语言不有一个 % 或 Mod()" - 2010 年就是这种情况,但没有更多。
    【解决方案6】:

    在javascript中:

    function modulo(num1, num2) {    
      if (num2 === 0 || isNaN(num1) || isNaN(num2)) {
        return NaN;
      }
    
      if (num1 === 0) {
        return 0;
      }
    
      var remainderIsPositive = num1 >= 0;
    
      num1 = Math.abs(num1);
      num2 = Math.abs(num2);
    
      while (num1 >= num2) {
        num1 -= num2
      }
    
      return remainderIsPositive ? num1 : 0 - num1;
    }
    

    【讨论】:

    • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性!
    【解决方案7】:

    如果有人迟到,这里有一些更实际的算法(有错误...仔细阅读)

    https://eprint.iacr.org/2014/755.pdf

    实际上有两种主要的归约公式:Barett 和 Montgomery。来自 eprint 的论文在不同版本(算法 1-3)中重复,并在算法 4 中给出了“改进”版本。

    概述

    我现在给出4.算法的概述:

    1.) 计算“A*B”并将整个乘积存储在“C”中,C 和模 $p$ 是该算法的输入。

    2.) 计算 $p$ 的位长,例如:函数“Width(p)”返回的正是那个值。

    3.) 将输入 $C$ 拆分为 N 个大小为“Width(p)”的“块”并将每个块存储在 G 中。从 G[0] = lsb(p) 开始,以 G[N-1 结束] = msb(p)。 (论文的描述确实有问题)

    4.) 开始 while 循环: 设置 N=N-1(到达最后一个元素) 预计算 $b:=2^{Width(p)} \bmod p$

    while N>0 do:
        T = G[N]
        for(i=0; i<Width(p); i++) do: //Note: that counter doesn't matter, it limits the loop)
            T = T << 1 //leftshift  by 1 bit
            while is_set( bit( T, Width(p) ) ) do // (N+1)-th bit of T is 1
                unset( bit( T, Width(p) ) ) // unset the (N+1)-th bit of T (==0)
                T += b
            endwhile
        endfor
        G[N-1] += T
        while is_set( bit( G[N-1], Width(p) ) ) do
            unset( bit( G[N-1], Width(p) ) ) 
            G[N-1] += b
        endwhile
        N -= 1
    endwhile
    

    这确实很多。不是我们只需要递归地减少 G[0]:

    while G[0] > p do
        G[0] -= p
    endwhile
    return G[0]// = C mod p
    

    其他三种算法定义明确,但这缺少一些信息或呈现出真正的错误。但它适用于任何尺寸;)

    【讨论】:

    • 嗨@shalec - 我们不鼓励只包含外部资源链接的答案。这些link-only-answers are discouraged.
    • 您可以将链接的 PDF 的相关部分复制并粘贴到您的答案中吗?这将大大提高这篇文章的质量。
    • 当然。提到了4种算法。我会编辑这些。
    猜你喜欢
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2023-03-23
    • 2019-04-14
    • 1970-01-01
    相关资源
    最近更新 更多