Menu

#17 Display of subnormal number leads to a crash

crash
open
5
2011-09-12
2011-09-12
Anonymous
No

Problem is in trio.c file line 3152

if (trio_isinf(workNumber)) {
/*
* Scaling is done it two steps to avoid problems with subnormal
* numbers.
*/
// Problem workNumber is not finite...
//workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2));
// correction
workNumber = number / TrioPower(dblBase, (trio_long_double_t)(exponent / 2));
workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2)));
}

Discussion

  • Bjorn Reese

    Bjorn Reese - 2011-09-18

    Do you have a test case that triggers the problem?

     
  • Nobody/Anonymous

    You can try the code below:
    trio_vsnprintf(buffer, sizeof(buffer), "%e", 1e-320);

    The crash was detected on Windows.

     
  • Bjorn Reese

    Bjorn Reese - 2011-09-24

    I cannot reproduce on Linux, and I have no Windows available.

    Could you show me the output of compiling trionan as standalone and running it?

    Off the top of my head (and probably wrong) you have to compile it like this:

    cl.exe /DSTANDALONE trionan.c /Fetrionan

     
  • Nobody/Anonymous

    Below the output obtained by compiling trionan as standalone:
    Nan : + FP_NAN 1.#QNAN
    PInf : + FP_INFINITE 1.#INF
    NInf : - FP_INFINITE -1.#INF
    PZero : + FP_ZERO 0
    NZero : - FP_ZERO -0
    PNorm : + FP_NORMAL 1
    NNorm : - FP_NORMAL -1
    PSub : + FP_SUBNORMAL 1e-309
    NSub : - FP_SUBNORMAL -1e-309
    NaN : 1.#QNAN 0x000000000000f87f ( 1, 0, 0)
    PInf: 1.#INF 0x000000000000f07f ( 0, 1, 0)
    NInf: -1.#INF 0x000000000000f0ff ( 0, -1, 0)
    NaN : -1.#IND 0x000000000000f8ff ( 1, 0, 0)
    PInf: 1.#INF 0x000000000000f07f ( 0, 1, 0)
    NInf: -1.#INF 0x000000000000f0ff ( 0, -1, 0)

    Even if the crash does not appear on Linux you should show the problem in the code.

    Line 3136 of trio.c file:
    if (trio_isinf(workNumber)) {
    /*
    * Scaling is done it two steps to avoid problems with subnormal
    * numbers.
    */
    workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2));
    workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2)));
    }

    The variable 'workNumber' is used in computation whereas it is not finite!
    Afterwards all computation made with 'workNumber' result in infinite results until:
    line 3552
    offset = (int)trio_fmod(workNumber, dblBase);
    ...
    // where offset will take a wrong value
    self->OutStream(self, digits[offset]);

     
MongoDB Logo MongoDB