Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 找到expmod的三元条件?_Javascript_Sicp - Fatal编程技术网

Javascript 找到expmod的三元条件?

Javascript 找到expmod的三元条件?,javascript,sicp,Javascript,Sicp,我正在阅读关于三元条件的非终止示例: function is_even(n) { return n % 2 === 0; } function expmod(base, exp, m) { const half_exp = expmod(base, exp / 2, m); return exp === 0 ? 1 : is_even(exp) ? half_exp * half_exp % m : base * expmod

我正在阅读关于三元条件的非终止示例:

function is_even(n) {
    return n % 2 === 0;
}

function expmod(base, exp, m) {
    const half_exp = expmod(base, exp / 2, m);
    return exp === 0 ? 1
           : is_even(exp) ? half_exp * half_exp % m
           : base * expmod(base, exp - 1, m) % m;
}

console.log(expmod(4, 3, 5))
它解释说:

这将使该功能不仅效率低下,而且实际上效率低下 不终止!问题是常量声明出现了 在条件表达式之外,这意味着它被执行 即使满足基本情况exp==0

我就是不明白它的意思,当exp==0时,它以1结尾,但为什么要执行half_exp呢

我就是不明白它的意思,当
exp===0
时,它以
1
终止,但为什么要执行half_exp呢

exp
0
时,表达式不以
1
终止,则为否<代码>经验===0?1:is_偶数(exp)将计算为
1
,整个表达式将作为下一个三元运算符的条件。由于
1
是一个实数值,因此整个表达式的计算结果将为
half_exp*half_exp%m

//Initial expression
(exp === 0 ? 1
   : is_even(exp)) ? (half_exp * half_exp % m)
   : (base * expmod(base, exp - 1, m) % m);

//Put exp = 1
(1 === 0 ? 1
   : is_even(exp)) ? (half_exp * half_exp % m)
   : (base * expmod(base, exp - 1, m) % m);

//Evaluate the first ternary expression
(1) ? (half_exp * half_exp % m)
   : (base * expmod(base, exp - 1, m) % m);

//The result of first will convert to boolean
Boolean(1) ? (half_exp * half_exp % m)
   : (base * expmod(base, exp - 1, m) % m);

//The result of first expression acts as condition for second ternary operator
true ? (half_exp * half_exp % m)
   : (base * expmod(base, exp - 1, m) % m);

//As condition is true to first expression is returned
(half_exp * half_exp % m)
 

您在第一行执行递归调用,不管执行什么。这意味着函数不是无限循环

function expmod(base, exp, m) {
    const half_exp = expmod(base, exp / 2, m); // <- recursive call
    // code ...
}
函数expmod(基,exp,m){
const half_exp=expmod(base,exp/2,m);//您误解的部分是变量初始化的方式和时间,而不是三元函数的工作方式。如果解释器已经到达,三元函数将按照您的想法工作


您已将
half\u exp
变量放入条件表达式中,并希望它在使用之前不会计算其初始值设定项

然而,这不是它的工作原理。

所有变量初始化语句(包括
var
let
const
在控件到达语句时立即对其初始值设定项进行评估,而不检查以后是否使用变量;并将初始值设定项的值存储到变量中

您可以通过运行以下代码段来查看它:

const foo=console.log(“我被执行了!”)

//`foo`从未被使用过,但代码将打印“我被执行了!”无论如何
我看不出这个无限递归示例与条件运算符有什么关系…基本上
函数expmod(){expmod();}
…你能澄清一下为什么你认为条件运算符在这里有任何不同吗?
真?1:false?0:2
被评估为
真?1:
,而不是
(真?1:false)?0:2
。所以我认为下面的句子是不正确的:
exp==0?1:is\u偶数(exp)
将计算为
1
,整个表达式将作为下一个三元运算符的条件。“您可以通过运行:
true?1:false?0:2/=>1
test with
true?1:false?0:2/=>1
,ty.@3limin4t0r它不会。我假设
const half\u exp=expmod(base,exp/2,m);
不是递归调用,因为没有继续的
返回
。此外,
expmod(base,exp/2,m)
可能在应用了一半exp后才会求值。在JavaScript中,函数一调用就会求值。赋值
expmod(base,exp/2,m)
half_exp
意味着递归调用就在此时进行,而不是在使用
half_exp
时进行。非常感谢您耐心的讲解,谢谢。