ldecNumber

Check-in [17e9bff5b9]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add duplicate context. Include setcontext in context methods. Add some rounding tests. Update doco.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:17e9bff5b9e3a615cec476d4764c0a9519146353
User & Date: e@6e5be3b1-1950-f047-a965-c680c9cf6ecc 2006-09-27 18:08:07
Context
2006-09-28
22:31
Add floor function and associated tests and doco. check-in: 655e4351ee user: e@6e5be3b1-1950-f047-a965-c680c9cf6ecc tags: trunk
2006-09-27
18:08
Add duplicate context. Include setcontext in context methods. Add some rounding tests. Update doco. check-in: 17e9bff5b9 user: e@6e5be3b1-1950-f047-a965-c680c9cf6ecc tags: trunk
2006-09-26
18:48
Fix typos in doco (thanks Mike!). check-in: 9853890ce4 user: e@6e5be3b1-1950-f047-a965-c680c9cf6ecc tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to doc/ldecNumber.odt.

cannot compute difference between binary files

Changes to ldecNumber.c.

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
...
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
...
464
465
466
467
468
469
470








471
472
473
474
475
476
477
...
672
673
674
675
676
677
678


679
680
681
682
683
684
685
static decContext *ldn_check_context (lua_State *L, int index)
{
    decContext *dc = (decContext *)luaL_checkudata (L, index, dn_context_meta);
    if (dc == NULL) luaL_argerror (L, index, "decNumber bad context");
    return dc; /* leaves context on Lua stack */
}

static decContext *ldn_make_context (lua_State *L, int32_t ctxflags)
{
    decContext *dc = (decContext *)lua_newuserdata(L, sizeof(decContext));
    dc = decContextDefault (dc, ctxflags);
    luaL_getmetatable (L, dn_context_meta);
    lua_setmetatable (L, -2); /* set metatable */
    return dc;  /* leaves context on Lua stack */
}

/* decContext cache */

................................................................................
    lua_pushthread (L);        /* key */
    lua_rawget (L, LUA_ENVIRONINDEX);
    
    if (lua_isnil (L, -1) )
    {
        /* nothing in the thread local state, so make a new context */
        lua_pop (L, 1);
        dc = ldn_make_context (L, LDN_CONTEXT_DEFAULT);

        /* make it the context for this thread */
        ldn_set_context (L, -1, dc);
    }
    else
    {
        dc = ldn_check_context (L, -1);
#if LDN_ENABLE_CACHE
................................................................................
    }
    else
    {
        luaL_error (L, "arg out of range for decNumber default");
    }
    return 0;
}









#define LDN_CTX_GETTER(field) \
static int dn_ctx_get_ ## field (lua_State *L) \
{ \
    decContext *dc = ldn_check_context (L, 1); \
    lua_pushinteger (L, dc->field); \
    return 1; \
................................................................................
    {"setclamp",         dn_ctx_set_clamp     },
#if DECSUBSET
    {"getextended",      dn_ctx_get_extended  },
    {"setextended",      dn_ctx_set_extended  },
#endif
    {"getstatusstring",  dn_ctx_get_status_s  },
    {"setstatusstring",  dn_ctx_set_status_s  },


    {"__tostring",       dn_ctx_tostring      },
    
    {NULL, NULL}
};

static const luaL_reg dn_lib[] =
{







|


<







 







|
>







 







>
>
>
>
>
>
>
>







 







>
>







107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
...
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
...
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
static decContext *ldn_check_context (lua_State *L, int index)
{
    decContext *dc = (decContext *)luaL_checkudata (L, index, dn_context_meta);
    if (dc == NULL) luaL_argerror (L, index, "decNumber bad context");
    return dc; /* leaves context on Lua stack */
}

static decContext *ldn_make_context (lua_State *L)
{
    decContext *dc = (decContext *)lua_newuserdata(L, sizeof(decContext));

    luaL_getmetatable (L, dn_context_meta);
    lua_setmetatable (L, -2); /* set metatable */
    return dc;  /* leaves context on Lua stack */
}

/* decContext cache */

................................................................................
    lua_pushthread (L);        /* key */
    lua_rawget (L, LUA_ENVIRONINDEX);
    
    if (lua_isnil (L, -1) )
    {
        /* nothing in the thread local state, so make a new context */
        lua_pop (L, 1);
        dc = ldn_make_context (L);
        dc = decContextDefault (dc, LDN_CONTEXT_DEFAULT);
        /* make it the context for this thread */
        ldn_set_context (L, -1, dc);
    }
    else
    {
        dc = ldn_check_context (L, -1);
#if LDN_ENABLE_CACHE
................................................................................
    }
    else
    {
        luaL_error (L, "arg out of range for decNumber default");
    }
    return 0;
}

static int dn_ctx_dup (lua_State *L) \
{
    decContext *dc = ldn_check_context (L, 1);
    decContext *dc_dup = ldn_make_context (L); /* new ctx on top of stack now */
    *dc_dup = *dc; /* copy context's fields */
    return 1;
}

#define LDN_CTX_GETTER(field) \
static int dn_ctx_get_ ## field (lua_State *L) \
{ \
    decContext *dc = ldn_check_context (L, 1); \
    lua_pushinteger (L, dc->field); \
    return 1; \
................................................................................
    {"setclamp",         dn_ctx_set_clamp     },
#if DECSUBSET
    {"getextended",      dn_ctx_get_extended  },
    {"setextended",      dn_ctx_set_extended  },
#endif
    {"getstatusstring",  dn_ctx_get_status_s  },
    {"setstatusstring",  dn_ctx_set_status_s  },
    {"duplicate",        dn_ctx_dup           },
    {"setcontext",       dn_set_context       },
    {"__tostring",       dn_ctx_tostring      },
    
    {NULL, NULL}
};

static const luaL_reg dn_lib[] =
{

Changes to test/ldecNumberUnitTest.lua.

339
340
341
342
343
344
345
346



































































































347
        assert_equal ((-a):remainder(-b),(-a) + b * (-a):divideinteger(-b))
        assert_qequal (a%b,decNumber.tonumber(x%y))
        assert_qequal ((-a)%b,decNumber.tonumber((-x)%y))
        assert_qequal (a%(-b),decNumber.tonumber(x%(-y)))
        assert_qequal ((-a)%(-b),decNumber.tonumber((-x)%(-y)))
    end
end




































































































lunit.run()








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
        assert_equal ((-a):remainder(-b),(-a) + b * (-a):divideinteger(-b))
        assert_qequal (a%b,decNumber.tonumber(x%y))
        assert_qequal ((-a)%b,decNumber.tonumber((-x)%y))
        assert_qequal (a%(-b),decNumber.tonumber(x%(-y)))
        assert_qequal ((-a)%(-b),decNumber.tonumber((-x)%(-y)))
    end
end

local round_funcs = lunit.TestCase("Rounding")

function round_funcs:test()
-- decNumber.ROUND_CEILING     round towards +infinity
-- decNumber.ROUND_UP          round away from 0
-- decNumber.ROUND_HALF_UP     0.5 rounds up
-- decNumber.ROUND_HALF_EVEN   0.5 rounds to nearest even
-- decNumber.ROUND_HALF_DOWN   0.5 rounds down
-- decNumber.ROUND_DOWN        round towards 0 (truncate)
-- decNumber.ROUND_FLOOR       round towards -infinity    local n = decNumber.tonumber "12.345"
    ctx = decNumber.getcontext()
    ctx:setdefault (decNumber.INIT_BASE)
    ctx:setdigits (5)
    local m = decNumber.tonumber "12.343"
    local n = decNumber.tonumber "12.345"
    local p = decNumber.tonumber "12.347"
    local d = decNumber.tonumber ".01"
    local q = decNumber.tonumber "2"
    ctx:setround(decNumber.ROUND_CEILING)
    assert_equal (m:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.34")
    ctx:setround(decNumber.ROUND_UP)
    assert_equal (m:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.35")
    assert_equal (n:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.35")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.35")
    ctx:setround(decNumber.ROUND_HALF_UP)
    assert_equal (m:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.35")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.35")
    ctx:setround(decNumber.ROUND_HALF_EVEN)
    assert_equal (m:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.35")
    ctx:setround(decNumber.ROUND_HALF_DOWN)
    assert_equal (m:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.35")
    ctx:setround(decNumber.ROUND_DOWN)
    assert_equal (m:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (p:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.34")
    ctx:setround(decNumber.ROUND_FLOOR)
    assert_equal (m:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.35")
    assert_equal (n:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.35")
    assert_equal (p:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.35")
end

function round_funcs:test_dup()
    ctx = decNumber.getcontext()
    dupc = ctx:duplicate()
    dupc:setdefault (decNumber.INIT_BASE)
    dupc:setdigits (5)
    dupc:setround(decNumber.ROUND_CEILING)
    dupe = dupc:duplicate()
    dupe:setround(decNumber.ROUND_HALF_UP)
    local m = decNumber.tonumber "12.343"
    local n = decNumber.tonumber "12.345"
    local p = decNumber.tonumber "12.347"
    local d = decNumber.tonumber ".01"
    local q = decNumber.tonumber "2"
    dupc:setcontext()
    assert_equal (m:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.34")
    decNumber.setcontext(dupe)
    assert_equal (m:quantize(d),decNumber.tonumber "12.34")
    assert_equal ((-m):quantize(d),decNumber.tonumber "-12.34")
    assert_equal (n:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-n):quantize(d),decNumber.tonumber "-12.35")
    assert_equal (p:quantize(d),decNumber.tonumber "12.35")
    assert_equal ((-p):quantize(d),decNumber.tonumber "-12.35")
    ctx:setcontext()
end

lunit.run()