为什么R语言自定义gcd函数传入19和-95返回结果为-19?
问题原因分析
你出现认知偏差的核心原因是对R的两个基础规则理解有误:
- 对
%%取模运算规则理解错误
R的取模运算遵循公式:a %% b = a - (b * floor(a/b)),运算结果的符号与除数b完全一致。你认为19 %% -95的结果是-19属于计算错误,实际计算结果为-76:
代入公式推导:19 / (-95) = -0.2,向下取整floor(-0.2) = -1,因此19 %% -95 = 19 - ((-95) * (-1)) = 19 - 95 = -76 - 对逻辑判断规则理解错误
R中做布尔判定时,只有数值0会被识别为FALSE,所有非0数值(无论正负)都会被识别为TRUE。哪怕r真的等于-19,也属于真值,会触发递归调用,不会直接返回y值。
递归执行过程拆解
我们完整拆解gcd(19,-95)的调用流程就能明确返回值来源:
- 第一层调用:x=19,y=-95
计算r = 19 %% -95 = -76,非0为真,递归调用gcd(-95, -76) - 第二层调用:x=-95,y=-76
计算r = (-95) %% (-76) = -95 - ((-76)floor(-95/-76)) = -95 - (-761) = -19,非0为真,递归调用gcd(-76, -19) - 第三层调用:x=-76,y=-19
计算r = (-76) %% (-19) = -76 - ((-19)floor(-76/-19)) = -76 - (-194) = 0,0为假,返回当前y值-19
因此最终运行结果为-19,和你实际测试的输出一致。
函数修正方案
如果需要返回正的最大公约数,只需要在计算前统一对输入取绝对值即可,修改后的代码如下:
gcd <- function(x,y) { x <- abs(x) y <- abs(y) r <- x%%y return(ifelse(r, gcd(y, r), y)) } # 测试 gcd(19,-95) # 返回19,符合预期
内容的提问来源于stack exchange,提问作者user16461886
相关产品推荐
相关产品推荐

