下面是我的代码完全正常,但我不允许使用'*'运算符。但在这种情况下,我不知道如何将负数转换为正数进行比较。一种选择是使用Math.abs,但我也不允许使用它。
var modulo = function(x, y) {
if ( x === 0 && y ===0 ) return NaN;
if ( x === y ) return 0;
if ( x === 0 ) return 0;
if (x > 0 && y > 0) {
return x < y ? x : modulo(x-y,y);
}
if ( x < 0 && y < 0 ) {
return x*-1 < y*-1 ? x : modulo(x-y,y);
}
if( x > 0 && y < 0 ) {
return x < y*-1 ? x : modulo(x+y,y);
}
if ( x < 0 && y >0) {
return x*-1 < y ? x : modulo(x+y,y);
}
};
答案 0 :(得分:2)
您可以使用一元减号运算符(-value
)或从零(0 - value
)减去数字来翻转数字符号。
无论哪种方式,都可以以比现在更简洁的方式实现模数:
var modulo = function(x, y) {
if (y === 0) { return NaN; }
if (x < 0) { return -modulo(-x, y); } // -27 % 4 -> -(27 % 4)
if (y < 0) { return modulo( x, -y); } // 27 % -4 -> 27 % 4
if (x < y) { return x; }
return modulo(x - y, y);
};
console.log(modulo( 27, 4)); // 3
console.log(modulo(-27, 4)); // -3
console.log(modulo( 27, -4)); // 3
console.log(modulo(-27, -4)); // -3
console.log(modulo(-32, 8)); // 0
仅用于奖励积分,这里是“真实”数学模的实现,也是在没有/
,*
或%
的情况下实现的:
var mathModulo = function(x, y) {
if (y <= 0) { return NaN; }
if (x >= 0 && x < y) { return x; }
return mathModulo(x - (x > 0 ? y : -y), y);
};
console.log(mathModulo( 27, 4)); // 3
console.log(mathModulo(-27, 4)); // 1
console.log(mathModulo( 27, -4)); // NaN
console.log(mathModulo(-27, -4)); // NaN
console.log(mathModulo(-32, 8)); // 0
答案 1 :(得分:1)
这是我怎么做的。你基本上只有几个案例:
y
为0
,请返回NaN
y
为负数,则转换为正数。x
为否定,则答案为-modulo(-x,y)x
小于y
,则答案为x
。x - y
modulo y
相同(这是递归部分)
var modulo = function(x, y) {
if (y === 0) return NaN;
if (y < 0) y = -y;
if (x < 0) return -modulo(-x, y);
if (x < y) return x;
return modulo(x - y, y);
};
console.log(modulo(4, 3), modulo(4, 3) === 4 % 3) // 1, true
console.log(modulo(-4, 3), modulo(-4, 3) === -4 % 3) // -1, true
console.log(modulo(4, -3), modulo(4, -3) === 4 % -3) // 1, true
console.log(modulo(-4, -3), modulo(-4, -3) === -4 % -3) // -1, true
&#13;
答案 2 :(得分:1)
我在Brainfuck完成了这项工作,你只有增量,减量和非零。以下是您如何做到这一点:
function modulo(n, m) {
function helper(acc, steps, diff) {
if (steps === 0) {
return helper(acc, m, 0);
} else if( acc === 0 ) {
return diff;
} else {
return helper(acc - 1, steps - 1, diff + 1);
}
}
return helper(n, m, 0);
}
console.log(12 % 5);
console.log(modulo(12, 5));
&#13;
我想你可以做这样的事情从消极变为积极:
function negToPos(a, b = 0) {
return a === 0 ? b : negToPos(a+1, b+1);
}
以下是Brainfuck的样子:
[->-[>+>>]>[+[-<+>]>+>>]<<<<<]
参数传递就像当前单元格一样,下一个包含divident和divizor,你得到第三个模数,第四个除以模数。想象一下,我已经完成了sqrt并在这里做了一个lisp解释器:-O
你不会在任何这些中获得零分,但它会让你在冬天保持温暖。 (需要ES6,因为它会在没有TCO的情况下炸掉堆栈)
更新在撰写本文时,我不知道有任何ES6实施。只有部分完成,与标准相比,某些功能会出现异常。大多数实现缺少的功能之一是TCO,但这并不会使我的ES6语句错误,因为它们不是ES6实现,如果不是100%标准兼容的话。对于尚未开发的ES6实现,您可以看到他们在compatibility table
中实施的语言是什么部分答案 3 :(得分:0)
您可以使用否定运算符。例如:
if ( x < 0 && y < 0 ) {
return -x < -y ? x : modulo(x-y,y);
}