1
4
5
30
31# include <luametatex.h>
32
33# include <decContext.h>
34# include <decNumber.h>
35
36# define DECIMAL_METATABLE "decimal number"
37
38typedef decNumber *decimal;
39
40static decContext context;
41
42# define min_precision 25
43# define default_precision 50
44# define max_precision 2500
45
46static void xdecimallib_initialize(void)
47{
48 decContextDefault(&context, DEC_INIT_BASE);
49 context.traps = 0;
50 context.emax = 999999;
51 context.emin = -999999;
52 context.digits = default_precision;
53}
54
55
60
61inline static decimal xdecimallib_push(lua_State *L)
62{
63 decimal p = lua_newuserdatauv(L, sizeof(decNumber), 0);
64 luaL_setmetatable(L, DECIMAL_METATABLE);
65 return p;
66}
67
68static void decNumberFromDouble(decNumber *A, double B, decContext *C)
69{
70 char buf[1000];
71 char *c;
72 snprintf(buf, 1000, "%-650.325lf", B);
73 c = buf;
74 while (*c++) {
75 if (*c == ' ') {
76 *c = '\0';
77 break;
78 }
79 }
80 decNumberFromString(A, buf, C);
81}
82
83inline static int xdecimallib_new(lua_State *L)
84{
85 decimal p = xdecimallib_push(L);
86 switch (lua_type(L, 1)) {
87 case LUA_TSTRING:
88 decNumberFromString(p, lua_tostring(L, 1), &context);
89 break;
90 case LUA_TNUMBER:
91 if (lua_isinteger(L, 1)) {
92 decNumberFromInt32(p, (int32_t) lua_tointeger(L, 1));
93 } else {
94 decNumberFromDouble(p, lua_tonumber(L, 1), &context);
95 }
96 break;
97 default:
98 decNumberZero(p);
99 break;
100 }
101 return 1;
102}
103
104
108
109static decimal xdecimallib_get(lua_State *L, int i)
110{
111 switch (lua_type(L, i)) {
112 case LUA_TUSERDATA:
113 return (decimal) luaL_checkudata(L, i, DECIMAL_METATABLE);
114 case LUA_TSTRING:
115 {
116 decimal p = xdecimallib_push(L);
117 decNumberFromString(p, lua_tostring(L, i), &context);
118 lua_replace(L, i);
119 return p;
120 }
121 case LUA_TNUMBER:
122 {
123 decimal p = xdecimallib_push(L);
124 if (lua_isinteger(L, i)) {
125 decNumberFromInt32(p, (int32_t) lua_tointeger(L, i));
126 } else {
127 decNumberFromDouble(p, lua_tonumber(L, i), &context);
128 }
129 lua_replace(L, i);
130 return p;
131 }
132 default:
133 {
134 decimal p = xdecimallib_push(L);
135 decNumberZero(p);
136 lua_replace(L, i);
137 return p;
138 }
139 }
140}
141
142static int xdecimallib_tostring(lua_State *L)
143{
144 decimal a = xdecimallib_get(L, 1);
145 luaL_Buffer buffer;
146 char *b = luaL_buffinitsize(L, &buffer, (size_t) a->digits + 14);
147 decNumberToString(a, b);
148 luaL_addsize(&buffer, strlen(b));
149 luaL_pushresult(&buffer);
150 return 1;
151}
152
153static int xdecimallib_toengstring(lua_State *L)
154{
155 decimal a = xdecimallib_get(L, 1);
156 luaL_Buffer buffer;
157 char *b = luaL_buffinitsize(L, &buffer, (size_t) a->digits + 14);
158 decNumberToEngString(a, b);
159 luaL_addsize(&buffer, strlen(b));
160 luaL_pushresult(&buffer);
161 return 1;
162}
163
164static int xdecimallib_tonumber(lua_State *L)
165{
166 decimal a = xdecimallib_get(L, 1);
167 char *buffer = lmt_memory_malloc((size_t) a->digits + 14);
168 if (buffer) {
169 double result = 0.0;
170 decNumberToString(a, buffer);
171 if (sscanf(buffer, "%lf", &result)) {
172 lua_pushnumber(L, result);
173 } else {
174 lua_pushnil(L);
175 }
176 lmt_memory_free(buffer);
177 return 1;
178 } else {
179 return 0;
180 }
181}
182
183static int xdecimallib_copy(lua_State *L)
184{
185 decimal a = xdecimallib_get(L, 1);
186 decimal p = xdecimallib_push(L);
187 decNumberCopy(p, a);
188 return 1;
189}
190
191static int xdecimallib_eq(lua_State *L)
192{
193 decNumber result;
194 decimal a = xdecimallib_get(L, 1);
195 decimal b = xdecimallib_get(L, 2);
196 decNumberCompare(&result, a, b, &context);
197 lua_pushboolean(L, decNumberIsZero(&result));
198 return 1;
199}
200
201static int xdecimallib_le(lua_State *L)
202{
203 decNumber result;
204 decimal a = xdecimallib_get(L, 1);
205 decimal b = xdecimallib_get(L, 2);
206 decNumberCompare(&result, a, b, &context);
207 lua_pushboolean(L, decNumberIsNegative(&result) || decNumberIsZero(&result));
208 return 1;
209}
210
211static int xdecimallib_lt(lua_State *L)
212{
213 decNumber result;
214 decimal a = xdecimallib_get(L, 1);
215 decimal b = xdecimallib_get(L, 2);
216 decNumberCompare(&result, a, b, &context);
217 lua_pushboolean(L, decNumberIsNegative(&result));
218 return 1;
219}
220
221static int xdecimallib_add(lua_State *L) {
222 decimal a = xdecimallib_get(L, 1);
223 decimal b = xdecimallib_get(L, 2);
224 decimal p = xdecimallib_push(L);
225 decNumberAdd(p, a, b, &context);
226 return 1;
227}
228
229static int xdecimallib_sub(lua_State *L) {
230 decimal a = xdecimallib_get(L, 1);
231 decimal b = xdecimallib_get(L, 2);
232 decimal p = xdecimallib_push(L);
233 decNumberSubtract(p, a, b, &context);
234 return 1;
235}
236
237static int xdecimallib_mul(lua_State *L) {
238 decimal a = xdecimallib_get(L, 1);
239 decimal b = xdecimallib_get(L, 2);
240 decimal p = xdecimallib_push(L);
241 decNumberMultiply(p, a, b, &context);
242 return 1;
243}
244
245static int xdecimallib_div(lua_State *L) {
246 decimal a = xdecimallib_get(L, 1);
247 decimal b = xdecimallib_get(L, 2);
248 decimal p = xdecimallib_push(L);
249 decNumberDivide(p, a, b, &context);
250 return 1;
251}
252
253static int xdecimallib_idiv(lua_State *L) {
254 decimal a = xdecimallib_get(L, 1);
255 decimal b = xdecimallib_get(L, 2);
256 decimal p = xdecimallib_push(L);
257 decNumberDivideInteger(p, a, b, &context);
258 return 1;
259}
260
261static int xdecimallib_mod(lua_State *L) {
262 decimal a = xdecimallib_get(L, 1);
263 decimal b = xdecimallib_get(L, 2);
264 decimal p = xdecimallib_push(L);
265 decNumberRemainder(p, a, b, &context);
266 return 1;
267}
268
269static int xdecimallib_neg(lua_State* L) {
270 decimal a = xdecimallib_get(L, 1);
271 decimal p = xdecimallib_push(L);
272 decNumberCopyNegate(p, a);
273 return 1;
274}
275
276static int xdecimallib_min(lua_State *L) {
277 decimal a = xdecimallib_get(L, 1);
278 decimal b = xdecimallib_get(L, 2);
279 decimal p = xdecimallib_push(L);
280 decNumberMin(p, a, b, &context);
281 return 1;
282}
283
284static int xdecimallib_max(lua_State *L) {
285 decimal a = xdecimallib_get(L, 1);
286 decimal b = xdecimallib_get(L, 2);
287 decimal p = xdecimallib_push(L);
288 decNumberMax(p, a, b, &context);
289 return 1;
290}
291
292static int xdecimallib_minus(lua_State* L) {
293 decimal a = xdecimallib_get(L, 1);
294 decimal p = xdecimallib_push(L);
295 decNumberNextMinus(p, a, &context);
296 return 1;
297}
298
299static int xdecimallib_plus(lua_State* L) {
300 decimal a = xdecimallib_get(L, 1);
301 decimal p = xdecimallib_push(L);
302 decNumberNextPlus(p, a, &context);
303 return 1;
304}
305
306static int xdecimallib_trim(lua_State* L) {
307 decimal a = xdecimallib_get(L, 1);
308 decNumberTrim(a);
309 return 0;
310}
311
312static int xdecimallib_pow(lua_State *L) {
313 decimal a = xdecimallib_get(L, 1);
314 decimal b = xdecimallib_get(L, 2);
315 decimal p = xdecimallib_push(L);
316 decNumberPower(p, a, b, &context);
317 return 1;
318}
319
320static int xdecimallib_abs(lua_State *L) {
321 decimal a = xdecimallib_get(L, 1);
322 decimal p = xdecimallib_push(L);
323 decNumberCopyAbs(p, a);
324 return 1;
325}
326
327static int xdecimallib_sqrt(lua_State *L) {
328 decimal a = xdecimallib_get(L, 1);
329 decimal p = xdecimallib_push(L);
330 decNumberSquareRoot(p, a, &context);
331 return 1;
332}
333
334static int xdecimallib_ln(lua_State *L) {
335 decimal a = xdecimallib_get(L, 1);
336 decimal p = xdecimallib_push(L);
337 decNumberLn(p, a, &context);
338 return 1;
339}
340
341static int xdecimallib_log10(lua_State *L) {
342 decimal a = xdecimallib_get(L, 1);
343 decimal p = xdecimallib_push(L);
344 decNumberLog10(p, a, &context);
345 return 1;
346}
347
348static int xdecimallib_exp(lua_State *L) {
349 decimal a = xdecimallib_get(L, 1);
350 decimal p = xdecimallib_push(L);
351 decNumberExp(p, a, &context);
352 return 1;
353}
354
355static int xdecimallib_rotate(lua_State *L) {
356 decimal a = xdecimallib_get(L, 1);
357 decimal b = xdecimallib_get(L, 2);
358 decimal p = xdecimallib_push(L);
359 decNumberRotate(p, a, b, &context);
360 return 1;
361}
362
363static int xdecimallib_shift(lua_State *L) {
364 decimal a = xdecimallib_get(L, 1);
365 decimal b = xdecimallib_get(L, 2);
366 decimal p = xdecimallib_push(L);
367 decNumberShift(p, a, b, &context);
368 return 1;
369}
370
371static int xdecimallib_left(lua_State *L) {
372 decimal a = xdecimallib_get(L, 1);
373 lua_Integer shift = luaL_optinteger(L, 2, 1);
374 decimal p = xdecimallib_push(L);
375 decNumber s;
376 decNumberFromInt32(&s, (int32_t) shift);
377 decNumberShift(p, a, &s, &context);
378 return 1;
379}
380
381static int xdecimallib_right(lua_State *L) {
382 decimal a = xdecimallib_get(L, 1);
383 lua_Integer shift = - luaL_optinteger(L, 2, 1);
384 decimal p = xdecimallib_push(L);
385 decNumber s;
386 decNumberFromInt32(&s, (int32_t) shift);
387 decNumberShift(p, a, &s, &context);
388 return 1;
389}
390
391static int xdecimallib_and(lua_State *L) {
392 decimal a = xdecimallib_get(L, 1);
393 decimal b = xdecimallib_get(L, 2);
394 decimal p = xdecimallib_push(L);
395 decNumberAnd(p, a, b, &context);
396 return 1;
397}
398
399static int xdecimallib_or(lua_State *L)
400{
401 decimal a = xdecimallib_get(L, 1);
402 decimal b = xdecimallib_get(L, 2);
403 decimal p = xdecimallib_push(L);
404 decNumberOr(p, a, b, &context);
405 return 1;
406}
407
408static int xdecimallib_xor(lua_State *L)
409{
410 decimal a = xdecimallib_get(L, 1);
411 decimal b = xdecimallib_get(L, 2);
412 decimal p = xdecimallib_push(L);
413 decNumberXor(p, a, b, &context);
414 return 1;
415}
416
417static int xdecimallib_setp(lua_State *L)
418{
419 int i = (int) luaL_optinteger(L, 1, default_precision);
420 if (i < min_precision) {
421 context.digits = min_precision;
422 } else if (i > max_precision) {
423 context.digits = max_precision;
424 } else {
425 context.digits = i;
426 }
427 lua_pushinteger(L, context.digits);
428 return 1;
429}
430
431static int xdecimallib_getp(lua_State *L)
432{
433 lua_pushinteger(L, context.digits);
434 return 1;
435}
436
437static const luaL_Reg xdecimallib_function_list[] =
438{
439
440 { "new", xdecimallib_new },
441 { "copy", xdecimallib_copy },
442 { "trim", xdecimallib_trim },
443 { "tostring", xdecimallib_tostring },
444 { "toengstring", xdecimallib_toengstring },
445 { "tonumber", xdecimallib_tonumber },
446 { "setprecision", xdecimallib_setp },
447 { "getprecision", xdecimallib_getp },
448
449 { "__add", xdecimallib_add },
450 { "__idiv", xdecimallib_idiv },
451 { "__div", xdecimallib_div },
452 { "__mod", xdecimallib_mod },
453 { "__eq", xdecimallib_eq },
454 { "__le", xdecimallib_le },
455 { "__lt", xdecimallib_lt },
456 { "__mul", xdecimallib_mul },
457 { "__sub", xdecimallib_sub },
458 { "__unm", xdecimallib_neg },
459 { "__pow", xdecimallib_pow },
460 { "__bor", xdecimallib_or },
461 { "__bxor", xdecimallib_xor },
462 { "__band", xdecimallib_and },
463 { "__shl", xdecimallib_left },
464 { "__shr", xdecimallib_right },
465
466 { "conj", xdecimallib_neg },
467 { "abs", xdecimallib_abs },
468 { "pow", xdecimallib_pow },
469 { "sqrt", xdecimallib_sqrt },
470 { "ln", xdecimallib_ln },
471 { "log", xdecimallib_log10 },
472 { "exp", xdecimallib_exp },
473 { "bor", xdecimallib_or },
474 { "bxor", xdecimallib_xor },
475 { "band", xdecimallib_and },
476 { "shift", xdecimallib_shift },
477 { "rotate", xdecimallib_rotate },
478 { "minus", xdecimallib_minus },
479 { "plus", xdecimallib_plus },
480 { "min", xdecimallib_min },
481 { "max", xdecimallib_max },
482
483 { NULL, NULL },
484};
485
486int luaopen_xdecimal(lua_State *L)
487{
488 xdecimallib_initialize();
489
490 luaL_newmetatable(L, DECIMAL_METATABLE);
491 luaL_setfuncs(L, xdecimallib_function_list, 0);
492 lua_pushliteral(L, "__index");
493 lua_pushvalue(L, -2);
494 lua_settable(L, -3);
495 lua_pushliteral(L, "__tostring");
496 lua_pushliteral(L, "tostring");
497 lua_gettable(L, -3);
498 lua_settable(L, -3);
499 lua_pushliteral(L, "__name");
500 lua_pushliteral(L, "decimal");
501 lua_settable(L, -3);
502 return 1;
503}
504 |