# 5.1.2机械设计中的抽象

> 译者： [https://sicp.comp.nus.edu.sg/chapters/97](https://sicp.comp.nus.edu.sg/chapters/97)

我们通常会定义一台包含&lt;quote&gt;原语&lt;/quote&gt;操作的机器，这些操作实际上非常复杂。 例如，在 [5.4](109)[5.5](114)基元&lt;/quote&gt;。

考虑一下GCD机器。 机器具有一条指令，该指令计算寄存器`a`和`b`的其余内容，并将结果分配给寄存器`t`。 如果要在不使用原始余数运算的情况下构造GCD机器，则必须指定如何根据更简单的运算（例如减法）来计算余数。 实际上，我们可以编写一个JavaScript函数来以这种方式找到余数：

```js
function remainder(n, d) {
    return n < d
        ? n
        : remainder(n - d, d);
}
```

因此，我们可以用减法运算和比较测试来代替GCD机器数据路径中的余数运算。 图 [5.5](97#fig_5.5) 显示了精巧机器的数据路径和控制器。 指令

<figure>![](img/c98bee1ae10da8288042c0e85dfda051.jpg)**[图5.5](97#fig_5.5)** 精心设计的GCD机器的数据路径和控制器。</figure>

```js
assign("t", list(op("rem"), reg("a"), reg("b")))
```

in the GCD controller definition is replaced by a sequence of instructions that contains a loop, as shown in figure <ref name="fig:gcd-machine-rem-controller">[5.6](97#fig_5.6)</ref>.

<figure>

```js
controller(
    "test-b",
    list(test(list(op("="), reg("b"), constant(0))),
         branch(label("gcd-done")),
         assign("t", reg("a")),
         "rem-loop",
         test(list((op "<"), reg("t"), reg("b"))),
         branch(label("rem-done")),
         assign("t", list(op("-"), reg("t"), reg("b"))),
         go_to(label("rem-loop")),
         "rem-done",
         assign("a", reg("b")),
         assign("b", reg("t")),
         go_to(label("test-b"))),
    "gcd-done");
```

**[Figure 5.6](97#fig_5.6)** Controller instruction sequence for the GCD machine in figure <ref name="fig:gcd-machine-rem">[5.5](97#fig_5.5)</ref>.</figure>

<exercise>Design a machine to compute square roots using Newton's method, as described in section <ref name="sec:sqrt">[1.1.7](9)</ref>:

```js
function sqrt(x) {
    function good_enough(guess, x) {
        return abs(square(guess) - x) < 0.001;
    }
    function improve(guess, x) {
        return average(guess, x / guess);
    }
    function sqrt_iter(guess, x) {
        return good_enough(guess, x)
            ? guess
            : sqrt_iter(improve(guess, x), x);
    }
    return  sqrt_iter(1.0);
}
```

Begin by assuming that `good_enough` and `improve` operations are available as primitives. Then show how to expand these in terms of arithmetic operations. Describe each version of the `sqrt` machine design by drawing a data-path diagram and writing a controller definition in the register-machine language.<button class="btn btn-secondary solution_btn" data-toggle="collapse" href="#no_solution_97_1_div">Add solution</button>There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in [Github](https://github.com/source-academy/sicp).</exercise>