我在parC中遇到过这段代码。
我无法理解它会发生在哪种情况(黄色标记)? 我的意思是当值类型为 Int 时,除法结果何时可以向上舍入?
答案 0 :(得分:2)
我对parC一无所知,但就C而言,你是对的:正值的整数除法被定义为截断分数,即向零舍入。
但是,代码中还有另一个错误:如果数组太长,可能会错误地计算中点。
准确地说,如果初始to
大于int
类型(INT_MAX
)中可表示的最大值的2或大于一半,那么递归调用之一将获得{ {1}}值大于(INT_MAX / 2)且表达式fr, to
将导致算术溢出。 (to+fr)
的结果将小于(to+fr)/2
。
为避免这种情况,建议使用fr/2
之类的表达式而不是fr + (to - fr)/2
。
修改强>
说明中也有错误!见图:
(4,5)→(4,5)递归比作者指示早一个级别发生,因此一个子树实际上不应出现在图中。另外,如果程序卡在红色箭头循环中,那么(6,5)递归将永远不会发生 - 该过程永远不会到达该分支。
有趣的是,作者显然忽略了他们绘画中出现的另一个循环;
递归(1,2)→(1,2)甚至比上面提到的更早出现:
作为旁注,我无法想象他们如何获得两个不同的划分相同范围的结果:
(4,5)→(4,5)+(6,5)和(4,5)→(4,5)+(5,5)
(见绿框)。可能他们如此专注于强迫上升的想法,他们忽略了对问题的所有其他方面的任何推理。
基于这个例子,我建议把这本书放在垃圾桶里。
答案 1 :(得分:1)
你是对的,C中正面操作数的整数除法总是四舍五入到除法的底部,检查this question以获取更多细节。我不熟悉parC,但据说full C++ language有一些来自其他语言的补充,所以描述的任务似乎不正确。
如果还有疑虑,您总是有机会直接检查任务:为parC设置environment,输入rsum()
的实施并执行rsum(A, 1, 5)
。
答案 2 :(得分:1)
您可能正在阅读超过18年的文字。
在C标准的旧版本中,具有负操作数的除法可以以实现定义的方式舍入:向下或向上。这意味着-3/2
可以根据编译器为您提供-1
或-2
。
这被认为是该语言的设计缺陷,并已通过C99标准进行了更正。如今,无论编译器如何,C总是使用“截断为零”。