Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm Burnikel和Ziegler算法2的Eiffel实现中的错误_Algorithm_Integer Division_Eiffel - Fatal编程技术网

Algorithm Burnikel和Ziegler算法2的Eiffel实现中的错误

Algorithm Burnikel和Ziegler算法2的Eiffel实现中的错误,algorithm,integer-division,eiffel,Algorithm,Integer Division,Eiffel,我需要另一双眼睛来告诉我我的Burnikel和Ziegler除法的Eiffel实现有什么问题,特别是“算法2-3n/2n”。埃菲尔铁塔的特点如下所示。“like Current”类型是一个数组列表[NATURAL_8]。换句话说,该实现使用包含8位值的数字(即肢体),因此数字以base-256为单位。随后会手动跟踪失败的调用。(很抱歉,参数太大,但我无法用较短的值再现错误。)在本例中,执行步骤遵循步骤3b 问题出在这里。该算法在第5步似乎很好,余数“r”的位数比除数多。我相信错误发生在步骤3b中

我需要另一双眼睛来告诉我我的Burnikel和Ziegler除法的Eiffel实现有什么问题,特别是“算法2-3n/2n”。埃菲尔铁塔的特点如下所示。“like Current”类型是一个数组列表[NATURAL_8]。换句话说,该实现使用包含8位值的数字(即肢体),因此数字以base-256为单位。随后会手动跟踪失败的调用。(很抱歉,参数太大,但我无法用较短的值再现错误。)在本例中,执行步骤遵循步骤3b

问题出在这里。该算法在第5步似乎很好,余数“r”的位数比除数多。我相信错误发生在步骤3b中,可能是调用了feature`one',它“应该”提供一个“Beta^n-1”的值。(也许我不明白B&Z的“Beta^n”符号

这是埃菲尔密码:

three_by_two_divide (a, a3, b: like Current): TUPLE [quot, rem: like Current]
        -- Called by `two_by_one_divide'.  It has similar structure as
        -- `div_three_halves_by_two_halfs', but the arguments to this
        -- function have type {JJ_BIG_NATURAL} instead of like `digit'.
        -- See Burnikel & Zieler, "Fast Recursive Division", pp 4-8,
        -- Algorithm 2.
    require
        n_not_odd: b.count >= div_limit and b.count \\ 2 = 0
        b_has_2n_digits: b.count = a3.count * 2
        a_has_2n_digits: a.count = a3.count * 2
    local
        n: INTEGER
        a1, a2: like Current
        b1, b2: like Current
        tup: TUPLE [quot, rem: like Current]
        q, q1, q2, r, r1: like Current
        c, d: like Current
    do
        n := b.count // 2
            -- 1) Split `a'
        a1 := new_sub_number (n + 1, a.count, a)
        a2 := new_sub_number (1, n.max (1), a)
            -- 2) Split `b'.
        b1 := new_sub_number (n + 1, b.count, b)
        b2 := new_sub_number (1, n.max (1), b)
            -- 3) Distinguish cases.
        if a1 < b1 then
                -- 3a) compute Q = floor ([A1,A2] / B1 with remainder.
            if b1.count < div_limit then
                tup := school_divide (a, b1)
            else
                tup := two_by_one_divide (a, b1)
            end
            q := tup.quot
            r1 := tup.rem
        else
                -- 3b) Q = beta^n - 1 and ...
            q := ones (n)
                -- ... R1 = [A1,A2] - [B1,0] + [0,B1] = [A1,A2] - QB1.
            r1 := a + b1
            if n > 1 then
                b1.shift_left (n)
            else
                b1.bit_shift_left (zero_digit.bit_count // 2)
            end
            r1.subtract (b1)
        end
            -- 4) D = Q * B2
        d := q * b2
            -- 5) R1 * B^n + A3 - D.  (The paper says "a4".)
        r1.shift_left (n)
        r := r1 + a3 - d
            -- 6) As long as R < 0, repeat
        from
        until not r.is_negative
        loop
            r := r + b
            q.decrement
        end
        check
            remainder_small_enough: r.count <= b.count
                -- because remainder must be less than divisor.
        end
        Result := [q, r]
    ensure
   --   n_digit_remainder: Result.rem.count = b.count // 2
        quotient_has_correct_count: Result.quot.count <= b.count // 2
    end
two除以三(a,a3,b:类电流):元组[quot,rem:like Current]
--由'two'u by'u one'u divide'调用。它的结构与
--‘三分之二除以二分之二’,但是这个论点
--函数的类型为{JJ_BIG_NATURAL},而不是类似“digit”。
--见Burnikel&Zieler,“快速递归除法”,第4-8页,
--算法2。
要求
n非奇数:b.count>=div\u限制和b.count\\2=0
b_有2个数字:b.count=a3.count*2
a_有2个数字:a.count=a3.count*2
地方的
n:整数
a1,a2:类电流
b1,b2:类电流
tup:TUPLE[quot,rem:like Current]
q、 q1、q2、r、r1:类电流
c、 d:像现在一样
做
n:=b.count//2
--1)拆分“a”
a1:=新的子编号(n+1,a.计数,a)
a2:=新的子编号(1,n.max(1),a)
--2)拆分“b”。
b1:=新的子编号(n+1,b.计数,b)
b2:=新的子编号(1,n.max(1),b)
--3)区分案例。
如果a11,则
b1.左移(n)
其他的
b1.位左移(零位。位计数//2)
结束
r1.减去(b1)
结束
--4)D=Q*B2
d:=q*b2
--5)R1*B^n+A3-D(纸上写着“a4”。)
r1.左移(n)
r:=r1+a3-d
--6)只要R<0,重复
从…起
直到r不为负
环
r:=r+b
q、 减量
结束
检查

余数足够小:r.count我建议检查
r1=[65114139,55,75,5,37151]
是否仍然相同,然后再执行
r1.shift\u left(n)
。有两种选择:

  • d:=q*b2
    影响
    r1
    ,但不应影响。很可能存在一些别名,即,
    r1
    与其他一些已更新的变量存在别名,应删除此别名
  • r1
    d:=q*b2
    之后仍然相同。问题在于
    shift_left
    无法(重新)初始化某些数据或使用不应使用的全局数据

  • 感谢Alexander,没有别名,也没有全局数据。我想我已经解决了这个问题,避免了对“一”的呼叫。Burnikel和Ziegler认为A除以B,“让A=Bβ^n,则获取一个新的_A:=A-B,并记住商以A 1开始。此时,A小于B,所以按照B&Z的说法继续。我还有一个问题,我会在一个新问题中发布。谢谢。我真的看不出用
    r1将
    [65114139,55,75,5,37151]
    左移4位有什么效果。左移(n)
    给出
    [227,25135184172220,37151,0,0,0,0]
    。如果您能够解释这种行为,将有助于理解实现。
    three_by_two_divide (a = [227,26,41,95,169,93,135,110], 
                         a3 = [92,164,19,39],
                         b =  [161,167,158,41,164,0,0,0]) 
    
        n := b.count // 2 = 4
            -- 1) Split `a'.
        a1 := new_sub_number (n + 1, a.count, a) = [227,26,41,95]
        a2 := new_sub_number (1, n.max (1), a) = [169,93,135,110]
            -- 2) Split `b'.
        b1 := new_sub_number (n + 1, b.count, b) = [161,167,158,41]
        b2 := new_sub_number (1, n.max (1), b) = [164,0,0,0]
            -- 3b) Q = beta^n -1 and ...
    --> q := ones (4) = [255,255,255,255]          <-- Is this the error?
            -- ... R1 = [A1,A2] - [B1,0] + [0,B1].
        r1 := a + b1 = [227,26,41,96,75,5,37,151]
        b1.shift_left (n) = [161,167,158,41,0,0,0,0]                        
        r1.subtract (b1) = [65,114,139,55,75,5,37,151]
        d := q * b2 = [163,255,255,255,92,0,0,0]
        r1.shift_left (n) = [227,25,135,184,172,220,37,151,0,0,0,0]   -- too big!
        r := r1 + a3 - d -= [227,25,135,184,8,220,37,152,0,164,19,39] -- too big!