From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Serge Petrenko Message-Id: <977F1A26-1374-4D64-8717-AB67F41E298F@tarantool.org> Content-Type: multipart/alternative; boundary="Apple-Mail=_2FEB2243-8B99-41F6-8AC6-09B2B08C31C4" Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: Re: [tarantool-patches] [PATCH 2/2] decimal: expose decimal type to lua. Date: Mon, 24 Jun 2019 17:53:47 +0300 In-Reply-To: <20190621155307.z6pnpfbgqgni6zud@esperanza> References: <89c41adbdf7452c1ef4a8f478363fe2ccb95a848.1560958964.git.sergepetrenko@tarantool.org> <20190621155307.z6pnpfbgqgni6zud@esperanza> To: Vladimir Davydov Cc: tarantool-patches@freelists.org List-ID: --Apple-Mail=_2FEB2243-8B99-41F6-8AC6-09B2B08C31C4 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hi! Thank you for review! I addressed your comments, and pushed the new version on the branch. The diff is below. It is rather big, but I feel like it belongs here, = rather than in a `v2` letter, since the changes are very minor. -- Serge Petrenko sergepetrenko@tarantool.org > 21 =D0=B8=D1=8E=D0=BD=D1=8F 2019 =D0=B3., =D0=B2 18:53, Vladimir = Davydov =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB= (=D0=B0): >=20 > On Wed, Jun 19, 2019 at 06:58:05PM +0300, Serge Petrenko wrote: >> Add a decimal library to lua. >>=20 >> Part of #692 >>=20 >> @TarantoolBot document >> Title: Document decimal module in lua. >>=20 >> First of all, you have to require the package via >> `decimal =3D require('decimal')` >> Now you can construct decimals via `tonumber` method. >> Decimals may be constructed from lua numbers, strings, unsigned and >> signed 64 bit integers. >> Decimal is a fixed-point type with maximum 38 digits of precision. = All >> the calculations are exact, so, be careful when constructing decimals >> from lua numbers: they may hold only 15 decimal digits of precision. >> You are advised to construct decimals from strings, since strings >> represent decimals exactly, and vice versa. >>=20 >> ``` >> a =3D decimal.tonumber(123e-7) >> b =3D decimal.tonumber('123.456') >> c =3D decimal.tonumber('123.456e2') >> d =3D decimal.tonumber(123ULL) >> e =3D decimal.tonumber(2) >> ``` >=20 > tonumber is a confusing name IMO. Let's rename it to decimal.new() Ok >=20 >> The allowed operations are addition, subtraction, division, >> multiplication and power. If at least one of the operands is decimal, >> decimal operations are performed. The other operand may be either >> decimal or string, containing a number representation, or a lua = number. >> When the operation is called as `decimal.opname`, both operands may = be >> strings or lua numbers, e.g. `decimal.add(23, '123.456') =3D=3D = 146.456`: >> ``` >=20 > Can these functions fail (overflow, underflow)? What happens on error? > Please mention in this document. I made the message more informative. >=20 >> tarantool> a + b >> --- >> - '123.456012300000000' >> ... >>=20 >> tarantool> decimal.add(a,b) >> --- >> - '123.456012300000000' >> ... >>=20 >> tarantool> c - d >> --- >> - '12222.6' >> ... >>=20 >> tarantool> decimal.sub(c,d) >=20 > I don't think we need decimal.add/sub/div/mul methods as long as we = have > corresponding operators. No problem. >=20 >> The following math functions are also supported: >> log10, ln, exp, sqrt, pow. When specified as >> `decimal.opname()`, operations may be performed on >> strings and lua numbers. >> ``` >> f =3D decimal.tonumber(100) >> tarantool> f:log10() >=20 > This looks weird. I think we should only allow decimal.log10(x), > not x:log10(). All the math functions are now accessed as decimal.func(), = decimal.scale() and decimal.precision() are added. >=20 >> --- >> src/CMakeLists.txt | 1 + >> src/lua/decimal.c | 327 = ++++++++++++++++++++++++++++++++++++++ >> src/lua/decimal.h | 39 +++++ >> src/lua/init.c | 2 + >> test/app/decimal.result | 172 ++++++++++++++++++++ >> test/app/decimal.test.lua | 50 ++++++ >> 6 files changed, 591 insertions(+) >> create mode 100644 src/lua/decimal.c >> create mode 100644 src/lua/decimal.h >> create mode 100644 test/app/decimal.result >> create mode 100644 test/app/decimal.test.lua >=20 > Please consider implementing this using Lua ffi. Take a look at > src/lua/uuid.lua for example. They say that ffi implementation is > generally faster than Lua C, because it doesn't break JIT traces. > It might be worth benchmarking the two approaches. I have written a proof-of-concept ffi implementation and tested its = performance. It has shown a ~25% performance decrease over the current = representation. The details are in the issue comments = (https://github.com/tarantool/tarantool/issues/692#issuecomment-505043929)= I propose to leave existing implementation as is. diff --git a/src/lua/decimal.c b/src/lua/decimal.c index 9e2fd41b5..4dc0dff7d 100644 --- a/src/lua/decimal.c +++ b/src/lua/decimal.c @@ -227,10 +227,10 @@ LDECIMAL_CMPOP(lt, <); LDECIMAL_CMPOP(le, <=3D); =20 static int -ldecimal_tonumber(struct lua_State *L) +ldecimal_new(struct lua_State *L) { if (lua_gettop(L) < 1) - luaL_error(L, "Usage: decimal.tonumber(value)"); + luaL_error(L, "Usage: decimal.new(value)"); lua_todecimal(L, 1); decimal_t *lhs =3D lua_checkdecimal(L, 1); decimal_t *res =3D lua_pushdecimal(L); @@ -251,6 +251,28 @@ ldecimal_round(struct lua_State *L) return 1; } =20 +static int +ldecimal_scale(struct lua_State *L) +{ + if (lua_gettop(L) < 1) + return luaL_error(L, "Usage: decimal.scale(decimal)"); + decimal_t *lhs =3D lua_checkdecimal(L, 1); + int scale =3D decimal_scale(lhs); + lua_pushnumber(L, scale); + return 1; +} + +static int +ldecimal_precision(struct lua_State *L) +{ + if (lua_gettop(L) < 1) + return luaL_error(L, "Usage: = decimal.precisiion(decimal)"); + decimal_t *lhs =3D lua_checkdecimal(L, 1); + int precision =3D decimal_precision(lhs); + lua_pushnumber(L, precision); + return 1; +} + static int ldecimal_tostring(struct lua_State *L) { @@ -262,14 +284,6 @@ ldecimal_tostring(struct lua_State *L) } =20 static const luaL_Reg ldecimal_mt[] =3D { - {"log10", ldecimal_log10}, - {"ln", ldecimal_ln}, - {"exp", ldecimal_exp}, - {"sqrt", ldecimal_sqrt}, - {"round", ldecimal_round}, - {"minus", ldecimal_minus}, - {"abs", ldecimal_abs}, - {"tostring", ldecimal_tostring}, {"__unm", ldecimal_minus}, {"__add", ldecimal_add}, {"__sub", ldecimal_sub}, @@ -284,23 +298,16 @@ static const luaL_Reg ldecimal_mt[] =3D { }; =20 static const luaL_Reg ldecimal_lib[] =3D { - {"eq", ldecimal_eq}, - {"lt", ldecimal_lt}, - {"le", ldecimal_le}, - {"add", ldecimal_add}, - {"sub", ldecimal_sub}, - {"mul", ldecimal_mul}, - {"div", ldecimal_div}, {"log10", ldecimal_log10}, {"ln", ldecimal_ln}, {"pow", ldecimal_pow}, {"exp", ldecimal_exp}, {"sqrt", ldecimal_sqrt}, {"round", ldecimal_round}, - {"minus", ldecimal_minus}, + {"scale", ldecimal_scale}, + {"precision", ldecimal_precision}, {"abs", ldecimal_abs}, - {"tostring", ldecimal_tostring}, - {"tonumber", ldecimal_tonumber}, + {"new", ldecimal_new}, {NULL, NULL} }; =20 diff --git a/test/app/decimal.result b/test/app/decimal.result index 93c1c7557..22590a082 100644 --- a/test/app/decimal.result +++ b/test/app/decimal.result @@ -5,69 +5,69 @@ test_run =3D require('test_run').new() --- ... -- check various constructors -decimal.tonumber('1234.5678') +decimal.new('1234.5678') --- - '1234.5678' ... -decimal.tonumber('1e6') +decimal.new('1e6') --- - '1000000' ... -decimal.tonumber('-6.234612e2') +decimal.new('-6.234612e2') --- - '-623.4612' ... -decimal.tonumber(tonumber64(2^63)) +decimal.new(tonumber64(2^63)) --- - '9223372036854775808.000000000000000' ... -decimal.tonumber(12345678ULL) +decimal.new(12345678ULL) --- - '12345678' ... -decimal.tonumber(-12345678LL) +decimal.new(-12345678LL) --- - '-12345678' ... -decimal.tonumber(1) +decimal.new(1) --- - '1.000000000000000' ... -decimal.tonumber(-1) +decimal.new(-1) --- - '-1.000000000000000' ... -decimal.tonumber(2^64) +decimal.new(2^64) --- - '18446744073709551616.000000000000000' ... -decimal.tonumber(2^(-20)) +decimal.new(2^(-20)) --- - '0.000000953674316' ... -a =3D decimal.tonumber('100') +a =3D decimal.new('100') --- ... -a:log10() +decimal.log10(a) --- - '2' ... -a:ln() +decimal.ln(a) --- - '4.6051701859880913680359829093687284152' ... -- overflow, e^100 > 10^38 -a:exp() +decimal.exp(a) --- - error: Operation failed ... -- e^87 < 10^38, no overflow, but rounds -- to 0 digits after the decimal point. -decimal.tonumber(87):exp() +decimal.exp(decimal.new(87)) --- - '60760302250568721495223289381302760753' ... -a:sqrt() +decimal.sqrt(a) --- - '10' ... @@ -75,26 +75,18 @@ a --- - '100' ... -a =3D decimal.tonumber('-123.456') +a =3D decimal.new('-123.456') --- ... -a:round(2) +decimal.round(a, 2) --- - '-123.46' ... -a:round(1) ---- -- '-123.5' -... -a:round(0) ---- -- '-123' -... -a:abs() +decimal.abs(a) --- - '123.456' ... -a:tostring() +a --- - '-123.456' ... @@ -122,11 +114,11 @@ a ^ 2 --- - '15241.383936' ... -a:abs() ^ 0.5 +decimal.abs(a) ^ 0.5 --- - '11.111075555498666484621494041182192341' ... -a:abs() ^ 0.5 =3D=3D a:abs():sqrt() +decimal.abs(a) ^ 0.5 =3D=3D decimal.sqrt(decimal.abs(a)) --- - true ... @@ -150,23 +142,3 @@ a =3D=3D a --- - true ... -decimal.tostring(a) ---- -- '-123.456' -... -a:tostring() ---- -- '-123.456' -... -decimal.abs(a) ---- -- '123.456' -... -decimal.minus(a) ---- -- '123.456' -... -decimal.round(a, 2) ---- -- '-123.46' -... diff --git a/test/app/decimal.test.lua b/test/app/decimal.test.lua index 4751c1500..b101f07b6 100644 --- a/test/app/decimal.test.lua +++ b/test/app/decimal.test.lua @@ -2,49 +2,41 @@ decimal =3D require('decimal') test_run =3D require('test_run').new() =20 -- check various constructors -decimal.tonumber('1234.5678') -decimal.tonumber('1e6') -decimal.tonumber('-6.234612e2') -decimal.tonumber(tonumber64(2^63)) -decimal.tonumber(12345678ULL) -decimal.tonumber(-12345678LL) -decimal.tonumber(1) -decimal.tonumber(-1) -decimal.tonumber(2^64) -decimal.tonumber(2^(-20)) +decimal.new('1234.5678') +decimal.new('1e6') +decimal.new('-6.234612e2') +decimal.new(tonumber64(2^63)) +decimal.new(12345678ULL) +decimal.new(-12345678LL) +decimal.new(1) +decimal.new(-1) +decimal.new(2^64) +decimal.new(2^(-20)) =20 -a =3D decimal.tonumber('100') -a:log10() -a:ln() +a =3D decimal.new('100') +decimal.log10(a) +decimal.ln(a) -- overflow, e^100 > 10^38 -a:exp() +decimal.exp(a) -- e^87 < 10^38, no overflow, but rounds -- to 0 digits after the decimal point. -decimal.tonumber(87):exp() -a:sqrt() +decimal.exp(decimal.new(87)) +decimal.sqrt(a) +a +a =3D decimal.new('-123.456') +decimal.round(a, 2) +decimal.abs(a) a -a =3D decimal.tonumber('-123.456') -a:round(2) -a:round(1) -a:round(0) -a:abs() -a:tostring() -a a / 10 a * 5 a + 17 a - 0.0001 a ^ 2 -a:abs() ^ 0.5 -a:abs() ^ 0.5 =3D=3D a:abs():sqrt() +decimal.abs(a) ^ 0.5 +decimal.abs(a) ^ 0.5 =3D=3D decimal.sqrt(decimal.abs(a)) a - 2 < a - 1 a + 1e-10 > a a <=3D a a >=3D a a =3D=3D a - -decimal.tostring(a) -a:tostring() -decimal.abs(a) -decimal.minus(a) -decimal.round(a, 2) --Apple-Mail=_2FEB2243-8B99-41F6-8AC6-09B2B08C31C4 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 Hi! Thank you for review!
I addressed your comments, and pushed the new version on the = branch.
The diff is below. It is rather big, but I = feel like it belongs here, rather than in
a `v2` = letter, since the changes are very minor.



21 =D0=B8=D1=8E=D0=BD=D1= =8F 2019 =D0=B3., =D0=B2 18:53, Vladimir Davydov <vdavydov.dev@gmail.com> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0= =B0=D0=BB(=D0=B0):

On Wed, Jun 19, 2019 at = 06:58:05PM +0300, Serge Petrenko wrote:
Add a = decimal library to lua.

Part of #692

@TarantoolBot document
Title: = Document decimal module in lua.

First of = all, you have to require the package via
`decimal =3D = require('decimal')`
Now you can construct decimals via = `tonumber` method.
Decimals may be constructed from lua = numbers, strings, unsigned and
signed 64 bit integers.
Decimal is a fixed-point type with maximum 38 digits of = precision. All
the calculations are exact, so, be careful = when constructing decimals
from lua numbers: they may hold = only 15 decimal digits of precision.
You are advised to = construct decimals from strings, since strings
represent = decimals exactly, and vice versa.

```
a =3D decimal.tonumber(123e-7)
b =3D = decimal.tonumber('123.456')
c =3D = decimal.tonumber('123.456e2')
d =3D = decimal.tonumber(123ULL)
e =3D decimal.tonumber(2)
```

tonumber is a = confusing name IMO. Let's rename it to decimal.new()

Ok


The = allowed operations are addition, subtraction, division,
multiplication and power. If at least one of the operands is = decimal,
decimal operations are performed. The other = operand may be either
decimal or string, containing a = number representation, or a lua number.
When the operation = is called as `decimal.opname`, both operands may be
strings = or lua numbers, e.g. `decimal.add(23, '123.456') =3D=3D 146.456`:
```

Can these = functions fail (overflow, underflow)? What happens on error?
Please mention in this document.

I made the = message more informative.


tarantool> a + b
---
- '123.456012300000000'
...

tarantool> decimal.add(a,b)
---
- '123.456012300000000'
...

tarantool> c - d
---
- '12222.6'
...

tarantool> decimal.sub(c,d)

I don't think we need decimal.add/sub/div/mul methods as long = as we have
corresponding operators.

No = problem.


The = following math functions are also supported:
log10, ln, = exp, sqrt, pow. When specified as
`decimal.opname()`, = operations may be performed on
strings and lua numbers.
```
f =3D decimal.tonumber(100)
tarantool> f:log10()

This looks weird. I think we should only allow = decimal.log10(x),
not x:log10().

All the = math functions are now accessed as decimal.func(), decimal.scale() = and
decimal.precision() are added.


---
src/CMakeLists.txt        |   1 +
src/lua/decimal.c         | 327 = ++++++++++++++++++++++++++++++++++++++
src/lua/decimal.h =         |  39 +++++
src/lua/init.c =            |   2 +
test/app/decimal.result   | 172 ++++++++++++++++++++
test/app/decimal.test.lua |  50 ++++++
6 = files changed, 591 insertions(+)
create mode 100644 = src/lua/decimal.c
create mode 100644 src/lua/decimal.h
create mode 100644 test/app/decimal.result
create= mode 100644 test/app/decimal.test.lua

Please consider implementing this using Lua ffi. Take a look = at
src/lua/uuid.lua for example. They say that ffi = implementation is
generally faster than Lua C, because it = doesn't break JIT traces.
It might be worth benchmarking = the two approaches.

I have written a proof-of-concept ffi implementation = and tested its performance.
It has shown a ~25% = performance decrease over the current representation.
I propose to leave existing = implementation as is.



diff --git a/src/lua/decimal.c b/src/lua/decimal.c
index 9e2fd41b5..4dc0dff7d 100644
--- = a/src/lua/decimal.c
+++ b/src/lua/decimal.c
@@= -227,10 +227,10 @@ LDECIMAL_CMPOP(lt, <);
 LDECIMAL_CMPOP(le, <=3D);
 
 static int
-ldecimal_tonumber(struct = lua_State *L)
+ldecimal_new(struct lua_State *L)
 {
  if (lua_gettop(L) < 1)
- = luaL_error(L, "Usage: decimal.tonumber(value)");
+ = luaL_error(L, "Usage: decimal.new(value)");
 = lua_todecimal(L, 1);
  decimal_t = *lhs =3D lua_checkdecimal(L, 1);
  decimal_t = *res =3D lua_pushdecimal(L);
@@ -251,6 +251,28 @@ = ldecimal_round(struct lua_State *L)
  return = 1;
 }
 
+static = int
+ldecimal_scale(struct lua_State *L)
+{+ = if (lua_gettop(L) < 1)
+ = return luaL_error(L, "Usage: decimal.scale(decimal)");
+ = decimal_t *lhs =3D lua_checkdecimal(L, 1);
+ int scale = =3D decimal_scale(lhs);
+ lua_pushnumber(L, scale);
+ = return 1;
+}
+
+static = int
+ldecimal_precision(struct lua_State *L)
+{
+ if (lua_gettop(L) < 1)
+ = return luaL_error(L, "Usage: decimal.precisiion(decimal)");
+ = decimal_t *lhs =3D lua_checkdecimal(L, 1);
+ int = precision =3D decimal_precision(lhs);
+ = lua_pushnumber(L, precision);
+ return = 1;
+}
+
 static int
 ldecimal_tostring(struct lua_State *L)
 {
@@ -262,14 +284,6 @@ = ldecimal_tostring(struct lua_State *L)
 }
 
 static const luaL_Reg = ldecimal_mt[] =3D {
- {"log10", ldecimal_log10},
- = {"ln", ldecimal_ln},
- {"exp", ldecimal_exp},
- = {"sqrt", ldecimal_sqrt},
- {"round", = ldecimal_round},
- {"minus", ldecimal_minus},
- = {"abs", ldecimal_abs},
- = {"tostring", ldecimal_tostring},
  {"__unm", = ldecimal_minus},
  {"__add", ldecimal_add},
 = {"__sub", ldecimal_sub},
@@ -284,23 +298,16 = @@ static const luaL_Reg ldecimal_mt[] =3D {
 };
 
 static const luaL_Reg = ldecimal_lib[] =3D {
- {"eq", ldecimal_eq},
- = {"lt", ldecimal_lt},
- {"le", ldecimal_le},
- = {"add", ldecimal_add},
- {"sub", = ldecimal_sub},
- {"mul", ldecimal_mul},
- = {"div", ldecimal_div},
  {"log10", = ldecimal_log10},
  {"ln", ldecimal_ln},
 = {"pow", ldecimal_pow},
  {"exp", = ldecimal_exp},
  {"sqrt", ldecimal_sqrt},
 = {"round", ldecimal_round},
- {"minus", = ldecimal_minus},
+ {"scale", ldecimal_scale},
+ = {"precision", ldecimal_precision},
  {"abs", = ldecimal_abs},
- {"tostring", = ldecimal_tostring},
- {"tonumber", = ldecimal_tonumber},
+ {"new", ldecimal_new},
 = {NULL, NULL}
 };
 diff --git a/test/app/decimal.result = b/test/app/decimal.result
index 93c1c7557..22590a082 = 100644
--- a/test/app/decimal.result
+++ = b/test/app/decimal.result
@@ -5,69 +5,69 @@ test_run =3D = require('test_run').new()
 ---
 ...
 -- check various = constructors
-decimal.tonumber('1234.5678')
+decimal.new('1234.5678')
 ---
 - '1234.5678'
 ...
-decimal.tonumber('1e6')
+decimal.new('1e6')
 ---
 - '1000000'
 ...
-decimal.tonumber('-6.234612e2')
+decimal.new('-6.234612e2')
 ---
 - '-623.4612'
 ...
-decimal.tonumber(tonumber64(2^63))
+decimal.new(tonumber64(2^63))
 ---
 - '9223372036854775808.000000000000000'
 ...
-decimal.tonumber(12345678ULL)
+decimal.new(12345678ULL)
 ---
 - '12345678'
 ...
-decimal.tonumber(-12345678LL)
+decimal.new(-12345678LL)
 ---
 - '-12345678'
 ...
-decimal.tonumber(1)
+decimal.new(1)
 ---
 - '1.000000000000000'
 ...
-decimal.tonumber(-1)
+decimal.new(-1)
 ---
 - = '-1.000000000000000'
 ...
-decimal.tonumber(2^64)
+decimal.new(2^64)
 ---
 - = '18446744073709551616.000000000000000'
 ...
-decimal.tonumber(2^(-20))
+decimal.new(2^(-20))
 ---
 - '0.000000953674316'
 ...
-a =3D decimal.tonumber('100')
+a =3D = decimal.new('100')
 ---
 ...
-a:log10()
+decimal.log10(a)
 ---
 - '2'
 ...
-a:ln()
+decimal.ln(a)
 --- - '4.6051701859880913680359829093687284152'
 ...
 -- overflow, e^100 > = 10^38
-a:exp()
+decimal.exp(a)
 ---
 - error: Operation failed
 ...
 -- e^87 < 10^38, no = overflow, but rounds
 -- to 0 digits after the = decimal point.
-decimal.tonumber(87):exp()
+decimal.exp(decimal.new(87))
 ---
 - '60760302250568721495223289381302760753'
 ...
-a:sqrt()
+decimal.sqrt(a)
 ---
 - = '10'
 ...
@@ -75,26 +75,18 @@ a
 ---
 - '100'
 ...
-a =3D = decimal.tonumber('-123.456')
+a =3D = decimal.new('-123.456')
 ---
 ...-a:round(2)
+decimal.round(a, 2)
 ---
 - '-123.46'
 ...
-a:round(1)
----
-- '-123.5'
-...
-a:round(0)
----
-- '-123'
-...
-a:abs()
+decimal.abs(a)
 ---
 - '123.456'
 ...
-a:tostring()
+a
 ---
 - '-123.456'
 ...
@@ -122,11 +114,11 @@ a ^ 2
 ---
 - '15241.383936'
 ...
-a:abs() ^ 0.5
+decimal.abs(a) ^ 0.5
 ---
 - '11.111075555498666484621494041182192341'
 ...
-a:abs() ^ 0.5 =3D=3D = a:abs():sqrt()
+decimal.abs(a) ^ 0.5 =3D=3D = decimal.sqrt(decimal.abs(a))
 ---
 -= true
 ...
@@ -150,23 +142,3 @@ a =3D=3D = a
 ---
 - true
 ...
-decimal.tostring(a)
----
-- '-123.456'
-...
-a:tostring()
----
-- = '-123.456'
-...
-decimal.abs(a)
----
-- '123.456'
-...
-decimal.minus(a)
----
-- = '123.456'
-...
-decimal.round(a, 2)
----
-- '-123.46'
-...
diff --git a/test/app/decimal.test.lua = b/test/app/decimal.test.lua
index 4751c1500..b101f07b6 = 100644
--- a/test/app/decimal.test.lua
+++ = b/test/app/decimal.test.lua
@@ -2,49 +2,41 @@ decimal =3D = require('decimal')
 test_run =3D = require('test_run').new()
 
 -- = check various constructors
-decimal.tonumber('1234.5678')-decimal.tonumber('1e6')
-decimal.tonumber('-6.234612e2')
-decimal.tonumber(tonumber64(2^63))
-decimal.tonumber(12345678ULL)
-decimal.tonumber(-12345678LL)
-decimal.tonumber(1)
-decimal.tonumber(-1)
-decimal.tonumber(2^64)
-decimal.tonumber(2^(-20))
+decimal.new('1234.5678')
+decimal.new('1e6')
+decimal.new('-6.234612e2')
+decimal.new(tonumber64(2^63))
+decimal.new(12345678ULL)
+decimal.new(-12345678LL)
+decimal.new(1)
+decimal.new(-1)
+decimal.new(2^64)
+decimal.new(2^(-20))
 
-a =3D= decimal.tonumber('100')
-a:log10()
-a:ln()+a =3D decimal.new('100')
+decimal.log10(a)
+decimal.ln(a)
 -- overflow, e^100 > = 10^38
-a:exp()
+decimal.exp(a)
 -- e^87 < 10^38, no overflow, but rounds
 -- to 0 digits after the decimal point.
-decimal.tonumber(87):exp()
-a:sqrt()
+decimal.exp(decimal.new(87))
+decimal.sqrt(a)+a
+a =3D decimal.new('-123.456')
+decimal.round(a, 2)
+decimal.abs(a)
 a
-a =3D decimal.tonumber('-123.456')
-a:round(2)
-a:round(1)
-a:round(0)
-a:abs()
-a:tostring()
 -a
 a / = 10
 a * 5
 a + 17
 a - 0.0001
 a ^ 2
-a:abs() ^ 0.5
-a:abs() ^ 0.5 =3D=3D = a:abs():sqrt()
+decimal.abs(a) ^ 0.5
+decimal.abs(a) ^ 0.5 =3D=3D decimal.sqrt(decimal.abs(a))
 a - 2 < a - 1
 a + 1e-10 > = a
 a <=3D a
 a >=3D a
 a =3D=3D a
-
-decimal.tostring(a)
-a:tostring()
-decimal.abs(a)
-decimal.minus(a)
-decimal.round(a, 2)

= --Apple-Mail=_2FEB2243-8B99-41F6-8AC6-09B2B08C31C4--