exp question - OS2

This is a discussion on exp question - OS2 ; In trying to track down a possible bug in bogofilter, I have found that exp() throws a floating point exception if given a more -tve argument than -708. I can't find any documented limits for this function. ? TIA -- ...

+ Reply to Thread
Results 1 to 17 of 17

Thread: exp question

  1. exp question

    In trying to track down a possible bug in bogofilter, I have found
    that exp() throws a floating point exception if given a more -tve
    argument than -708.

    I can't find any documented limits for this function. ?

    TIA
    --
    Regards
    Dave Saville

    NB Remove nospam. for good email address

  2. Re: exp question

    [A complimentary Cc of this posting was sent to
    Dave Saville
    ], who wrote in article :
    > In trying to track down a possible bug in bogofilter, I have found
    > that exp() throws a floating point exception if given a more -tve
    > argument than -708.


    Your CRTL is buggy. The FPE should be masked by default. (Google for
    numerous threads discussing how FPE may be unmasked due to bugs in
    startup code of IBM DLLs.)

    > I can't find any documented limits for this function. ?


    It is not exactly the "function"; it is the limit of the return value.
    doubles support values up to about 1e304 and 1e-304; floats smaller.
    Wiki for IEEE floats.

    Hope this helps,
    Ilya


  3. Re: exp question

    On Mon, 26 May 2008 01:45:11 UTC, Ilya Zakharevich
    wrote:

    > [A complimentary Cc of this posting was sent to
    > Dave Saville
    > ], who wrote in article :
    > > In trying to track down a possible bug in bogofilter, I have found
    > > that exp() throws a floating point exception if given a more -tve
    > > argument than -708.

    >
    > Your CRTL is buggy. The FPE should be masked by default. (Google for
    > numerous threads discussing how FPE may be unmasked due to bugs in
    > startup code of IBM DLLs.)
    >
    > > I can't find any documented limits for this function. ?

    >
    > It is not exactly the "function"; it is the limit of the return value.
    > doubles support values up to about 1e304 and 1e-304; floats smaller.
    > Wiki for IEEE floats.


    Hmm, I just ran the same code on my Solaris box and around the same
    value it sets errno to ERANGE(34) but keeps on going (the returned
    value being 0). Are we really talking IBM code here? Using latest GCC.


    --
    Regards
    Dave Saville

    NB Remove nospam. for good email address

  4. Re: exp question

    [A complimentary Cc of this posting was sent to
    Dave Saville
    ], who wrote in article :
    > Hmm, I just ran the same code on my Solaris box and around the same
    > value it sets errno to ERANGE(34) but keeps on going (the returned
    > value being 0).


    Yes, this is what is supposed to happen.

    > Are we really talking IBM code here? Using latest GCC.


    I doubt that you get any problem like this in a "short test program".
    Most probably it is during loading some external DLLs that the
    processor flags are stomped over.

    Hope this helps,
    Ilya

  5. Re: exp question

    Ilya Zakharevich wrote:
    > [A complimentary Cc of this posting was sent to
    > Dave Saville
    > ], who wrote in article :
    >
    >>Hmm, I just ran the same code on my Solaris box and around the same
    >>value it sets errno to ERANGE(34) but keeps on going (the returned
    >>value being 0).

    >
    >
    > Yes, this is what is supposed to happen.
    >
    >
    >>Are we really talking IBM code here? Using latest GCC.

    >
    >
    > I doubt that you get any problem like this in a "short test program".
    > Most probably it is during loading some external DLLs that the
    > processor flags are stomped over.
    >
    > Hope this helps,
    > Ilya


    A lot of IBM code does this. I found out that open for stdout does, at
    least when it's a VIO window. Never checked any farther. My PL/I
    compiler had problems with this, now I just automatically restore the
    flags on return from any "foreign" code, and don't have any problems.
    Ypu'd think that libc would do the same.


  6. Re: exp question

    [A complimentary Cc of this posting was sent to
    Peter Flass
    ], who wrote in article <483b161f$0$30186$4c368faf@roadrunner.com>:
    > > I doubt that you get any problem like this in a "short test program".
    > > Most probably it is during loading some external DLLs that the
    > > processor flags are stomped over.


    > A lot of IBM code does this. I found out that open for stdout does, at
    > least when it's a VIO window.


    My experience is exactly the opposite. Opening /dev/con never lead to
    any problem. Depending on the "auto-load DLL list" (forgot the name
    of the INI file entry), the FIRST write to /dev/con can trigger some
    misbehaving code (GAMESRVR.DLL - of DIVE - being the culprit in my case).

    > Ypu'd think that libc would do the same.


    This may be a serious workaround. In perl, I'm not that anal, and
    restore the flags in three situations only (those which case problem on
    all the systems):

    a) on startup (due to DLLs already pre-loaded);
    b) when loading a DLL explicitely;
    c) when morphing to PM (or back) - apparently, this loads some DLLs.

    Hope this helps,
    Ilya

    P.S. Aha, I googled for myself and GAMESRVR, and found the INI file
    setting: PM_HOOKS.

  7. Re: exp question

    On Mon, 26 May 2008 14:16:32 UTC, Ilya Zakharevich
    wrote:

    > [A complimentary Cc of this posting was sent to
    > Dave Saville
    > ], who wrote in article :
    > > Hmm, I just ran the same code on my Solaris box and around the same
    > > value it sets errno to ERANGE(34) but keeps on going (the returned
    > > value being 0).

    >
    > Yes, this is what is supposed to happen.
    >
    > > Are we really talking IBM code here? Using latest GCC.

    >
    > I doubt that you get any problem like this in a "short test program".
    > Most probably it is during loading some external DLLs that the
    > processor flags are stomped over.


    Well I complied the test under EMX and it keeps going like Solaris,
    but does not set errno - just returns zero. So I am forced to think
    there is a bug in libc0x* for the latest GCC.

    --
    Regards
    Dave Saville

    NB Remove nospam. for good email address

  8. Re: exp question

    On 05/27/08 08:41 am, Dave Saville wrote:
    > On Mon, 26 May 2008 14:16:32 UTC, Ilya Zakharevich
    > wrote:
    >
    >> [A complimentary Cc of this posting was sent to
    >> Dave Saville
    >> ], who wrote in article:
    >>> Hmm, I just ran the same code on my Solaris box and around the same
    >>> value it sets errno to ERANGE(34) but keeps on going (the returned
    >>> value being 0).

    >> Yes, this is what is supposed to happen.
    >>
    >>> Are we really talking IBM code here? Using latest GCC.

    >> I doubt that you get any problem like this in a "short test program".
    >> Most probably it is during loading some external DLLs that the
    >> processor flags are stomped over.

    >
    > Well I complied the test under EMX and it keeps going like Solaris,
    > but does not set errno - just returns zero. So I am forced to think
    > there is a bug in libc0x* for the latest GCC.
    >


    The bug is in the PM which is IBM code. Perhaps Knut should of added a
    workaround, wouldn't hurt to post on the libc list and ask.
    Doodle added this to Cairo to work around it, perhaps try it?

    static void inline
    DisableFPUException (void)
    {
    unsigned short usCW;

    /* Some OS/2 PM API calls modify the FPU Control Word,
    * but forget to restore it.
    *
    * This can result in XCPT_FLOAT_INVALID_OPCODE exceptions,
    * so to be sure, we disable Invalid Opcode FPU exception
    * before using FPU stuffs.
    */
    usCW = _control87 (0, 0);
    usCW = usCW | EM_INVALID | 0x80;
    _control87 (usCW, MCW_EM | 0x80);
    }

    Dave

  9. Re: exp question

    On Wed, 28 May 2008 00:23:52 UTC, Dave Yeo
    wrote:

    > The bug is in the PM which is IBM code. Perhaps Knut should of added a
    > workaround, wouldn't hurt to post on the libc list and ask.
    > Doodle added this to Cairo to work around it, perhaps try it?
    >
    > static void inline
    > DisableFPUException (void)
    > {
    > unsigned short usCW;
    >
    > /* Some OS/2 PM API calls modify the FPU Control Word,
    > * but forget to restore it.
    > *
    > * This can result in XCPT_FLOAT_INVALID_OPCODE exceptions,
    > * so to be sure, we disable Invalid Opcode FPU exception
    > * before using FPU stuffs.
    > */
    > usCW = _control87 (0, 0);
    > usCW = usCW | EM_INVALID | 0x80;
    > _control87 (usCW, MCW_EM | 0x80);
    > }


    Yes but according to the Solaris man page exp() should return 0 and
    ERANGE on underflow and MAX_VALUE and ERANGE on overflow. The above
    "fix" will not acheive that.

    Is it possible to somehow redirect exp() calls elsewhere, do a range
    check and then call the "real" exp() ? Without manually changing every
    call to exp() - there are lots of 'em sprinkled throughout bogofilter.


    --
    Regards
    Dave Saville

    NB Remove nospam. for good email address

  10. Re: exp question

    In , on 06/01/2008
    at 10:33 AM, "Dave Saville" said:

    Hi,

    >Yes but according to the Solaris man page exp() should return 0 and
    >ERANGE on underflow and MAX_VALUE and ERANGE on overflow. The above
    >"fix" will not acheive that.


    >Is it possible to somehow redirect exp() calls elsewhere, do a range
    >check and then call the "real" exp() ? Without manually changing every
    >call to exp() - there are lots of 'em sprinkled throughout bogofilter.


    Why not just install an exception handler and map the exception to the
    result you want.

    Steven

    --
    --------------------------------------------------------------------------------------------
    Steven Levine MR2/ICE 3.00 beta 11pre11 #10183
    eCS/Warp/DIY/14.103a_W4 www.scoug.com irc.ca.webbnet.info #scoug (Wed 7pm PST)
    --------------------------------------------------------------------------------------------


  11. Re: exp question

    On Sun, 1 Jun 2008 16:11:59 UTC, Steven Levine
    wrote:

    > In , on 06/01/2008
    > at 10:33 AM, "Dave Saville" said:
    >
    > Hi,
    >
    > >Yes but according to the Solaris man page exp() should return 0 and
    > >ERANGE on underflow and MAX_VALUE and ERANGE on overflow. The above
    > >"fix" will not acheive that.

    >
    > >Is it possible to somehow redirect exp() calls elsewhere, do a range
    > >check and then call the "real" exp() ? Without manually changing every
    > >call to exp() - there are lots of 'em sprinkled throughout bogofilter.

    >
    > Why not just install an exception handler and map the exception to the
    > result you want.


    If I knew how..... Can you continue execution from where you were
    after trapping an exception and influence the result you wanted it to
    get? I don't think so. But very willing to be shown how :-)

    --
    Regards
    Dave Saville

    NB Remove nospam. for good email address

  12. Re: exp question

    On Sun, 1 Jun 2008 16:11:59 UTC, Steven Levine
    wrote:

    > Why not just install an exception handler and map the exception to the
    > result you want.


    I have tried an exception handler that catches FP underflow and says
    to continue - but it does not. Well not exactly.

    code snippet

    for ( i=701; a != 0.0; i++ )
    {
    a = (double)-i;
    printf("%d %f ", i, a);
    a = exp(a);
    printf("%e %d\n", a, errno);
    }

    My exception prints "Underflow" and returns XCPT_CONTINUE_EXECUTION
    Which promptly generates another Underflow. I just get loads of them
    rather than interspersed with the printf's above. I need to make exp()
    return 0 on underflow and MAX_VALUE on overflow. I don't think you can
    this way. Hence my original question.

    --
    Regards
    Dave Saville

    NB Remove nospam. for good email address

  13. Re: exp question

    On Sun, 1 Jun 2008 16:11:59 UTC, Steven Levine
    wrote:

    > In , on 06/01/2008
    > at 10:33 AM, "Dave Saville" said:
    >
    > Hi,
    >
    > >Yes but according to the Solaris man page exp() should return 0 and
    > >ERANGE on underflow and MAX_VALUE and ERANGE on overflow. The above
    > >"fix" will not acheive that.

    >
    > >Is it possible to somehow redirect exp() calls elsewhere, do a range
    > >check and then call the "real" exp() ? Without manually changing every
    > >call to exp() - there are lots of 'em sprinkled throughout bogofilter.

    >
    > Why not just install an exception handler and map the exception to the
    > result you want.


    Bit of lateral thinking and one can get the C preprocessor to do all
    the work for you. No crashes in BF Yipee. :-)

    --
    Regards
    Dave Saville

    NB Remove nospam. for good email address

  14. Re: exp question

    [A complimentary Cc of this posting was sent to
    Dave Saville
    ], who wrote in article :
    > On Sun, 1 Jun 2008 16:11:59 UTC, Steven Levine
    > wrote:
    >
    > > Why not just install an exception handler and map the exception to the
    > > result you want.

    >
    > I have tried an exception handler that catches FP underflow and says
    > to continue - but it does not. Well not exactly.
    >
    > code snippet
    >
    > for ( i=701; a != 0.0; i++ )
    > {
    > a = (double)-i;
    > printf("%d %f ", i, a);
    > a = exp(a);
    > printf("%e %d\n", a, errno);
    > }
    >
    > My exception prints "Underflow" and returns XCPT_CONTINUE_EXECUTION
    > Which promptly generates another Underflow. I just get loads of them
    > rather than interspersed with the printf's above. I need to make exp()
    > return 0 on underflow and MAX_VALUE on overflow. I don't think you can
    > this way. Hence my original question.


    What is your problem? Just disable SIGFPU, and inspect the result of
    the "correct" exp(), and mutiliate it the way you want.

    Hope this helps,
    Ilya

  15. Re: exp question

    Dave Saville wrote:
    > On Sun, 1 Jun 2008 16:11:59 UTC, Steven Levine
    > wrote:
    >
    >
    >>Why not just install an exception handler and map the exception to the
    >>result you want.

    >
    >
    > I have tried an exception handler that catches FP underflow and says
    > to continue - but it does not. Well not exactly.
    >
    > code snippet
    >
    > for ( i=701; a != 0.0; i++ )
    > {
    > a = (double)-i;
    > printf("%d %f ", i, a);
    > a = exp(a);
    > printf("%e %d\n", a, errno);
    > }
    >
    > My exception prints "Underflow" and returns XCPT_CONTINUE_EXECUTION
    > Which promptly generates another Underflow. I just get loads of them
    > rather than interspersed with the printf's above. I need to make exp()
    > return 0 on underflow and MAX_VALUE on overflow. I don't think you can
    > this way. Hence my original question.
    >


    I believe the handler has to clear the exception bits in the FPU status
    works, and maybe also set the saved ST(0) to the result you want. The
    saved FPU information is in the context area when the exception handler
    is entered.


  16. Re: exp question

    In , on 06/01/2008
    at 04:43 PM, "Dave Saville" said:

    Hi,

    >If I knew how..... Can you continue execution from where you were after
    >trapping an exception and influence the result you wanted it to get? I
    >don't think so. But very willing to be shown how :-)


    You can. Modify the registers passed in the context record.

    Steven

    --
    --------------------------------------------------------------------------------------------
    Steven Levine MR2/ICE 3.00 beta 11pre11 #10183
    eCS/Warp/DIY/14.103a_W4 www.scoug.com irc.ca.webbnet.info #scoug (Wed 7pm PST)
    --------------------------------------------------------------------------------------------


  17. Re: exp question

    [A complimentary Cc of this posting was sent to
    Peter Flass
    ], who wrote in article <4842fc91$0$5723$4c368faf@roadrunner.com>:
    > > My exception prints "Underflow" and returns XCPT_CONTINUE_EXECUTION
    > > Which promptly generates another Underflow. I just get loads of them
    > > rather than interspersed with the printf's above. I need to make exp()
    > > return 0 on underflow and MAX_VALUE on overflow. I don't think you can
    > > this way. Hence my original question.


    > I believe the handler has to clear the exception bits in the FPU status
    > works, and maybe also set the saved ST(0) to the result you want. The
    > saved FPU information is in the context area when the exception handler
    > is entered.


    IIRC what Scott wrote about a decade ago, after v2.11 (or some such),
    the kernel does not provide enough context to implement restartable FP
    exceptions. (But my understanding of the involved issues is very
    limited.)

    Hope this helps,
    Ilya

+ Reply to Thread