SICP - 通过添加进行乘法运算

时间:2016-09-12 00:30:27

标签: lisp racket sicp

我正在使用SICP这本书并试图解决这个问题:

  

1.2.4 Exponentiation

     

练习1.18。使用练习1.16和1.17的结果,设计   生成迭代过程以乘以2的过程   在添加,加倍和减半方面的整数并使用a   对数步数

我试图用以下代码解决这个问题:

Mage::app()->getStore($order->getStoreId())->getName());

正如您可能看到的那样,我试图先处理偶数。 我正在使用SICP wiki as my solutions-guide。他们建议进行一些测试以查看代码是否有效:

(define (double x) 
  (+ x x))

(define (halve x) 
  (floor (/ x 2)))

(define (* a b)
  (define (iter count accumulate)
    (cond ((= count 1) accumulate)
          ((even? a) (iter (halve count) (+ accumulate (double b))))
          (else empty)))
  (iter a 0))

我没有得到的是我的代码传递了这两个首次测试,只处理偶数。

然而,当我尝试一些2的倍数的大数字时,代码失败了。我使用Python检查了结果。例如,

 (* 2 4) 
 (* 4 0) 

当我在Dr. Racket中使用我的函数时,我得到了不同的结果:

(IN PYTHON)

2**100  
>> 1267650600228229401496703205376  
2**98
>> 316912650057057350374175801344
a = 2**100
b = 2**98
a*b
>> 401734511064747568885490523085290650630550748445698208825344

我的结果是:63382530011411470074835160268800,这是错误的,因为Python内置函数建议。

为什么会这样?

1 个答案:

答案 0 :(得分:1)

递归步骤似乎是错误的,empty在那里做什么?另外,如果b是否定的,会发生什么?这个解决方案应该有效:

(define (mul a b)
  (define (iter a b acc)
    (cond ((zero? b) acc)
          ((even? b) (iter (double a) (halve b) acc))
          (else (iter a (- b 1) (+ a acc)))))
  (if (< b 0)
      (- (iter a (- b) 0))
      (iter a b 0)))

例如:

(mul 1267650600228229401496703205376 316912650057057350374175801344)
=> 401734511064747568885490523085290650630550748445698208825344