# Help needed testing decimal package

**URL:** <https://discuss.ocaml.org/t/help-needed-testing-decimal-package/6772>\
**Category:** Ecosystem\
**Created:** [November 15, 2020, 9:58pm UTC](https://discuss.ocaml.org/t/help-needed-testing-decimal-package/6772 "2020-11-15T21:58:29Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [November 15, 2020, 9:58pm UTC](https://discuss.ocaml.org/t/help-needed-testing-decimal-package/6772/1 "2020-11-15T21:58:29Z")

</div>

Hi, I’ve been working on a `decimal` package: [https://github.com/yawaramin/ocaml-decimal](https://github.com/yawaramin/ocaml-decimal) (arbitrary-precision floating-point decimals).

I’ve published a _very early preview_ on opam: [http://opam.ocaml.org/packages/decimal/](http://opam.ocaml.org/packages/decimal/)

You can try it out:

```auto
$ opam install decimal
$ utop
#
  #require "decimal";;
#
  module D = Decimal
  let i = D.of_int
  let s = D.of_string;;
#
  #install_printer D.pp;;
#
  D.(s "0.1" + s "0.2");;
- : D.t = 0.3
# (* default precision is 32 *)
  D.(i 1 / i 3);;
- : D.t = 0.33333333333333333333333333333333

```

The module is basically a port of the [Python decimal](https://docs.python.org/3/library/decimal.html) module, with some simplifications like, I’m ignoring different types of NaN like negative NaN, quiet NaN, signalling NaN, and just treating them all as NaN. Otherwise I aim to have the same functionality.

What I need help with mainly is porting the Python `decimal` unit tests: [https://github.com/python/cpython/tree/23831a7a90956e38b7d70304bb6afe30d37936de/Lib/test/decimaltestdata](https://github.com/python/cpython/tree/23831a7a90956e38b7d70304bb6afe30d37936de/Lib/test/decimaltestdata) . They are written in a plain-text DSL consisting of test cases like:

```auto
addx6324 add 0.12 0.01 -> 0.13

```

And I assume they have an interpreter somewhere that parses and runs these tests as standard Python unit tests.

What I would like to do is to port these tests into plain OCaml. The above test case could look like (e.g. Alcotest):

```auto
check string "addx6324" "0.13" D.(to_string (s "0.12" + s "0.01"))

```

The test DSL has a few more features, like comments and setting and checking flags, but not too much more complex. So I would really appreciate some help with porting them. I was thinking good old regular expressions to do the conversions, but I’m open to suggestions.

---

<div class="post-metadata">

**Author:** ![ulrikstrid](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ulrikstrid/32/1600_2.png) [@ulrikstrid](https://discuss.ocaml.org/u/ulrikstrid)\
**Post date:** [November 16, 2020, 6:59am UTC](https://discuss.ocaml.org/t/help-needed-testing-decimal-package/6772/2 "2020-11-16T06:59:31Z")

</div>

It might be worth it to write a small interpreter for it, that way you don’t have to add new tests when the python library does, you can just sync their changes.

But since I have a fetish for regex:  
`([a-z0-9]+) +add +(['\-\+0-9\.E]+) +(['\-\+0-9\.E]+) +-> +([\-'\+0-9\.E]+)`  
`check string "$1" "$4" D.(to_string (s "$2" + s "$3"))`

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [November 16, 2020, 2:23pm UTC](https://discuss.ocaml.org/t/help-needed-testing-decimal-package/6772/3 "2020-11-16T14:23:03Z")

</div>

Thanks Ulrik! Yes, I do believe this data file format is simple enough for regex 🙂

---

<div class="post-metadata">

**Author:** ![steinuil](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/steinuil/32/993_2.png) [@steinuil](https://discuss.ocaml.org/u/steinuil)\
**Post date:** [November 17, 2020, 1:38am UTC](https://discuss.ocaml.org/t/help-needed-testing-decimal-package/6772/4 "2020-11-17T01:38:02Z")

</div>

I don’t like regex and I’m a big fan of parser combinators, so I actually went ahead and wrote a parser using Angstrom because I was feeling very bored 🙂

> <https://gist.github.com/steinuil/6d18802aebada1b463a2db3520bb6986>

I’ve tried it on the latest version of the test files which is located here [http://speleotrove.com/decimal/](http://speleotrove.com/decimal/) and it parses everything without issues. The only part that’s missing is parsing the numbers themselves (I left it for last because it looked very annoying to do correctly).

As for actually running the tests, you could either generate some ocaml files from the AST and then run them (possibly easier debugging?), or interpret the AST directly (less error prone).

The source files look generally like this:

```auto
version: 2.62

precision: 9
rounding: half_up
maxExponent: 384
minexponent: -383
extended: 1

addx001 add 1 1 -> 2
addx002 add 2 3 -> 5
addx003 add '5.75' '3.3' -> 9.05
addx004 add '5' '-3' -> 2
addx005 add '-5' '-3' -> -8
-- ...
rounding: half_even
addx220 add '123456789' 0 -> '123456789'
addx221 add '123456789' 0.000000001 -> '123456789' Inexact Rounded
addx222 add '123456789' 0.000001 -> '123456789' Inexact Rounded
-- ...
precision: 3
rounding: half_up
addx270 add '12345678900000' 9999999999999 -> '2.23E+13' Inexact Rounded
addx271 add '9999999999999' 12345678900000 -> '2.23E+13' Inexact Rounded

```

The overall structure is basically:

- initial configuration
- test cases
- changes to configuration
- test cases
- …

So maybe you could render these different configuration/test cases sections as different test suites, each with their own configuration.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [November 17, 2020, 1:39am UTC](https://discuss.ocaml.org/t/help-needed-testing-decimal-package/6772/5 "2020-11-17T01:39:49Z")

</div>

Wow! Was not expecting that. Thank you!!! Taking a look now.

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [November 17, 2020, 3:07am UTC](https://discuss.ocaml.org/t/help-needed-testing-decimal-package/6772/6 "2020-11-17T03:07:26Z")

</div>

OK I think I’ve made a good start on evaluating this parsed format: [https://github.com/yawaramin/ocaml-decimal/blob/test/test/decimal\_test.ml](https://github.com/yawaramin/ocaml-decimal/blob/test/test/decimal_test.ml)

Will make more progress tomorrow. Thanks again!
