在Ocaml中减法,我无法确定这个bug

时间:2016-10-24 03:53:30

标签: functional-programming ocaml

let rec sub' list1 list2 carry = match (list1, list2, carry) with
    | list1, [], 0       -> list1
    | [], list2, 0       -> list2
    | list1, [], carry   -> sub' list1 [carry] 0
    | [], list2, carry   -> sub' [carry] list2 0
    | car1::cdr1, car2::cdr2, carry ->
      let minus = car1 - car2 + carry



       in  minus mod radix :: sub' cdr1 cdr2 (minus / radix)

基数设置为10

所以,这是我必须减去两个数字(list1和list2)的代码。这基于我修改的给定代码,所以我不完全确定它是如何工作的。然而,对于大多数事情它确实有效。 5 - 4 = 1 10 - 20 = -10等。

但是,对于较大的数字,它有这个奇怪的错误,100 - 50 =“1-50”这是接近的,它有我们想要的“50”,但有一些额外的垃圾。

我一直试图解决这个问题,而且我很困难。

编辑:

let length    = List.length
let car       = List.hd
let cdr       = List.tl
let map       = List.map
let reverse   = List.rev
let strcat    = String.concat
let strlen    = String.length
let strsub    = String.sub
let zero      = Bigint (Pos, [])



let rec zeros' rev = 
if (car rev) = 0 then
  lead_zeros' (cdr rev)
else (reverse rev)

let zeros list = match list with
| [0] -> list
| [] -> []
| list -> let reversed = reverse list
          in lead_zeros' reversed

1 个答案:

答案 0 :(得分:1)

我没有完全分析你的代码,但是我认为问题在于分割为零,而你需要它向下舍入。例如,(-3) / 5 = 0(-3) mod 5 = -3,而您需要(-3) / 5 = -1(-3) mod 5 = 2

似乎不变量为minus >= -radix,因此一个简单的解决方法是将radix添加到minus并相应地调整所有其他内容:

let minus = car1 - car2 + carry + radix
  in  minus mod radix :: sub' cdr1 cdr2 (minus / radix - 1)

这会将除法和模数转换为非负范围,它会按预期工作。