Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #54647 > unrolled thread

C program. run time abend, range fault.

Started byShiva <subramanian.klu@gmail.com>
First post2014-12-16 00:47 -0800
Last post2015-01-01 14:38 -0800
Articles 20 on this page of 52 — 16 participants

Back to article view | Back to comp.lang.c


Contents

  C program. run time abend, range fault. Shiva <subramanian.klu@gmail.com> - 2014-12-16 00:47 -0800
    Re: C program. run time abend, range fault. jt@toerring.de (Jens Thoms Toerring) - 2014-12-16 10:31 +0000
      Re: C program. run time abend, range fault. Shiva <subramanian.klu@gmail.com> - 2014-12-16 11:33 -0800
        Re: C program. run time abend, range fault. Barry Schwarz <schwarzb@dqel.com> - 2014-12-16 14:27 -0800
        Re: C program. run time abend, range fault. jt@toerring.de (Jens Thoms Toerring) - 2014-12-16 23:08 +0000
        Re: C program. run time abend, range fault. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-16 23:44 +0000
      Re: C program. run time abend, range fault. glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-12-16 19:37 +0000
        Re: C program. run time abend, range fault. jt@toerring.de (Jens Thoms Toerring) - 2014-12-17 00:12 +0000
          Re: C program. run time abend, range fault. Shiva <subramanian.klu@gmail.com> - 2014-12-17 13:05 -0800
            Re: C program. run time abend, range fault. Barry Schwarz <schwarzb@dqel.com> - 2014-12-17 15:06 -0800
              Re: C program. run time abend, range fault. Richard Heathfield <invalid@see.sig.invalid> - 2014-12-17 23:15 +0000
                Re: C program. run time abend, range fault. Keith Thompson <kst-u@mib.org> - 2014-12-17 16:00 -0800
              Re: C program. run time abend, range fault. Keith Thompson <kst-u@mib.org> - 2014-12-17 15:56 -0800
              Re: C program. run time abend, range fault. Shiva <subramanian.klu@gmail.com> - 2014-12-18 12:28 -0800
                Re: C program. run time abend, range fault. Barry Schwarz <schwarzb@dqel.com> - 2014-12-18 14:07 -0800
                Re: C program. run time abend, range fault. Barry Schwarz <schwarzb@dqel.com> - 2014-12-18 14:16 -0800
                Re: C program. run time abend, range fault. jacob navia <jacob@spamsink.net> - 2014-12-19 00:55 +0100
                Re: C program. run time abend, range fault. jt@toerring.de (Jens Thoms Toerring) - 2014-12-19 00:18 +0000
                Re: C program. run time abend, range fault. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-19 01:12 +0000
            Re: C program. run time abend, range fault. jt@toerring.de (Jens Thoms Toerring) - 2014-12-18 01:00 +0000
            Re: C program. run time abend, range fault. James Kuyper <jameskuyper@verizon.net> - 2014-12-17 22:29 -0500
              Re: C program. run time abend, range fault. gazelle@shell.xmission.com (Kenny McCormack) - 2014-12-18 09:18 +0000
                Re: C program. run time abend, range fault. Martin Shobe <martin.shobe@yahoo.com> - 2014-12-18 11:10 -0600
                  Re: C program. run time abend, range fault. Shiva <subramanian.klu@gmail.com> - 2014-12-18 11:38 -0800
                    Re: C program. run time abend, range fault. James Kuyper <jameskuyper@verizon.net> - 2014-12-18 15:24 -0500
                      Re: C program. run time abend, range fault. Shiva <subramanian.klu@gmail.com> - 2014-12-18 12:37 -0800
    C program. run time abend, range fault. asetofsymbols@gmail.com - 2014-12-18 22:21 -0800
    Re: C program. run time abend, range fault. Is this the correct solution? jacob navia <jacob@spamsink.net> - 2014-12-19 18:32 +0100
      Re: C program. run time abend, range fault. Is this the correct solution? jacob navia <jacob@spamsink.net> - 2014-12-20 11:34 +0100
        Re: C program. run time abend, range fault. Is this the correct solution? Shiva <subramanian.klu@gmail.com> - 2014-12-31 11:48 -0800
          Re: C program. run time abend, range fault. Is this the correct solution? James Kuyper <jameskuyper@verizon.net> - 2014-12-31 15:49 -0500
          Re: C program. run time abend, range fault. Is this the correct solution? Keith Thompson <kst-u@mib.org> - 2014-12-31 13:07 -0800
            Re: C program. run time abend, range fault. Is this the correct solution? Geoff <geoff@invalid.invalid> - 2014-12-31 13:57 -0800
              Re: C program. run time abend, range fault. Is this the correct solution? Keith Thompson <kst-u@mib.org> - 2014-12-31 16:02 -0800
                Re: C program. run time abend, range fault. Is this the correct solution? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-31 22:55 -0800
              Re: C program. run time abend, range fault. Is this the correct solution? raltbos@xs4all.nl (Richard Bos) - 2015-01-05 14:56 +0000
          Re: C program. run time abend, range fault. Is this the correct solution? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-31 21:51 +0000
          Re: C program. run time abend, range fault. Is this the correct solution? jacob navia <jacob@spamsink.net> - 2015-01-01 02:51 +0100
            Re: C program. run time abend, range fault. Is this the correct solution? raltbos@xs4all.nl (Richard Bos) - 2015-01-05 15:00 +0000
              Re: C program. run time abend, range fault. Is this the correct solution? Shiva <subramanian.klu@gmail.com> - 2015-01-05 09:45 -0800
                Re: C program. run time abend, range fault. Is this the correct solution? Geoff <geoff@invalid.invalid> - 2015-01-05 11:02 -0800
                  Re: C program. run time abend, range fault. Is this the correct solution? Shiva <subramanian.klu@gmail.com> - 2015-01-06 10:33 -0800
                    Re: C program. run time abend, range fault. Is this the correct solution? James Kuyper <jameskuyper@verizon.net> - 2015-01-06 14:09 -0500
                      Re: C program. run time abend, range fault. Is this the correct solution? Shiva <subramanian.klu@gmail.com> - 2015-01-06 12:32 -0800
                        Re: C program. run time abend, range fault. Is this the correct solution? James Kuyper <jameskuyper@verizon.net> - 2015-01-06 15:47 -0500
                    Re: C program. run time abend, range fault. Is this the correct solution? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-01-06 23:58 +0000
                      Re: C program. run time abend, range fault. Is this the correct solution? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-01-07 04:31 +0000
                        Re: C program. run time abend, range fault. Is this the correct solution? Robert Wessel <robertwessel2@yahoo.com> - 2015-01-06 23:36 -0600
                        Re: C program. run time abend, range fault. Is this the correct solution? Richard Heathfield <invalid@see.sig.invalid> - 2015-01-07 07:08 +0000
                          Re: C program. run time abend, range fault. Is this the correct solution? Shiva <subramanian.klu@gmail.com> - 2015-01-09 13:46 -0800
              Re: C program. run time abend, range fault. Is this the correct solution? Geoff <geoff@invalid.invalid> - 2015-01-05 09:56 -0800
    Re: C program. run time abend, range fault. Geoff <geoff@invalid.invalid> - 2015-01-01 14:38 -0800

Page 1 of 3  [1] 2 3  Next page →


#54647 — C program. run time abend, range fault.

FromShiva <subramanian.klu@gmail.com>
Date2014-12-16 00:47 -0800
SubjectC program. run time abend, range fault.
Message-ID<3636bf65-fa27-43a6-b54f-45477b249b5d@googlegroups.com>
There's an arithmetic program that I wrote in C. It was converted from fortran. For the same inputs the fortran code does not give out any run time abends but my C code does. No compilation errors, but run time abends as follows:

Run time error: Range fault.
In funcB.
In funcC.
In XXXX program.

Pardon the weirdness in stating the run time error in such a way. But in the environment that I use, this is how it is blurted out. So my program has three functions and a main function - of which CALCZ-MATCH-FUNC and CALCZ-FUNC are two of them. Now I have complex exponential statements within these functions. Within the CALCX-MATCH-FUNC, CALCZ-FUNC is called once and that's when the range fault occurs as it is trying to do the following (1/10 ^ (-72)).

I understand that this should produce a range fault as the resultant value goes out of bounds. But I want to catch this error from within the program and I don't want it to abend at run time. Any range fault or calculation overflow has to be catched because in run time the program should not fail. Can it redirect and set some flag or return some output when this happens so that the calling program doesn't have to abend as well, if this program abends. 

I strictly have to use just C in this environment. And I have the errors.h library header file. I'm not sure how to use it here.


The following is the code:

    long long int funcA (long long int  pA, long long int pB,long long int pC,long long int pD, long long int pF, long long int pN)

    {
    ... Initialisation...

    funcB (A, pF, pN, pD, pC, pB, pA, z);

    ...initialisations value assigning to other variables...A


    funcB (A, pF, pN, pD, pC, pB, pA, z);

    do
    {

     funcC (A, pF, pN, pD, pC, pB, pA, v, w, x, y, z);

     count = count + 1;

     } while (((z >= 0.0001) || (z <= 0.0001)) && count < limit);

     if ( count = limit)
     A = -1;

    else
    {
     ... Some more math..
     }
     return A;
     }


     void funcB (double A, int pF, int pN, int pD, double pC, double pB, double pA, double z)

     {

     z = (pow (A, pF) * (A - 1)) / (1 - (pow (A, -pN)));

     z = pB / z;
     z = z - pA - (pC / pow (A, pD));

     }

     void funcC (double A, int pF, int pN, int pD, int pC, double pB, double pa, double v, double w, double x, double y, double z)

     {

     A = some math...

     calcz (A, pF, pN, pD, PC, pB, pA, z);

     Some more math...

     }

The funcA is called by a Cobol program, and this C program compiles fine. But only during run time there's an error. The input is just 6 values. pA, pB, pC, pD, pF, pN. 

If you see in funcC it calls funcB whose first line of code does a complex exponential calculation which overflows at some particular iteration, resulting in the range fault like I stated earlier. 

Inputs:

      pA = 1000
      pB = 44.50
      pN = 25
      pC = 0
      pD = 2
      pF = 2

These are correct inputs for which program works fine. Only for a few weird inputs passed, like below, it gives the range fault. 

      pA = 1000
      pB = 144.50
      pN = 25
      pC = 0
      pD = 2
      pF = 2

I just need to catch this error in run time and tell the calling program that this is a bad input. I don't want the program to fail. Because it would cause the calling program to fail as well. Could this be accomplished in C itself? 


[toc] | [next] | [standalone]


#54651

Fromjt@toerring.de (Jens Thoms Toerring)
Date2014-12-16 10:31 +0000
Message-ID<cfag0nF9r44U1@mid.uni-berlin.de>
In reply to#54647
Shiva <subramanian.klu@gmail.com> wrote:
> There's an arithmetic program that I wrote in C. It was converted from
> fortran. For the same inputs the fortran code does not give out any
> run time abends but my C code does. No compilation errors, but run
> time abends as follows:

> Run time error: Range fault.
> In funcB.
> In funcC.
> In XXXX program.

> Pardon the weirdness in stating the run time error in such a way. But
> in the environment that I use, this is how it is blurted out. So my
> program has three functions and a main function - of which
> CALCZ-MATCH-FUNC and CALCZ-FUNC are two of them. Now I have complex
> exponential statements within these functions. Within the
> CALCX-MATCH-FUNC, CALCZ-FUNC is called once and that's when the range
> fault occurs as it is trying to do the following (1/10 ^ (-72)).

> I understand that this should produce a range fault as the resultant
> value goes out of bounds. But I want to catch this error from within
> the program and I don't want it to abend at run time. Any range fault
> or calculation overflow has to be catched because in run time the
> program should not fail. Can it redirect and set some flag or return
> some output when this happens so that the calling program doesn't have
> to abend as well, if this program abends.

> I strictly have to use just C in this environment. And I have the
> errors.h library header file. I'm not sure how to use it here.

Note that this 'erros.h' header file is not a standard C
header file and perhaps specific to the library. Since you
don't mention which library you're using it's hard to even
guess what this file might contain.

> The following is the code:

>     long long int funcA (long long int  pA, long long int pB,long long int pC,long long int pD, long long int pF, long long int pN)
>     {
>     ... Initialisation...
>     funcB (A, pF, pN, pD, pC, pB, pA, z);
>     ...initialisations value assigning to other variables...A

>     funcB (A, pF, pN, pD, pC, pB, pA, z);
>     do
>     {
>      funcC (A, pF, pN, pD, pC, pB, pA, v, w, x, y, z);
>      count = count + 1;
>      } while (((z >= 0.0001) || (z <= 0.0001)) && count < limit);

Here seems to be somthing very wrong. In C values are passed
to functions by value. That means that what funcB() and funcA()
receive e.g. for 'A' is the value 'A' has in the caller. Any
modifications these functions make to 'A' (or the other argu-
ments) are strictly local to these functions and un. Consider a very
simple program like this:

#include <stdio.h>

void foo( int x ) {
    x = 7;
}

int main( void ) {
    int a = 3;
    foo( a );
    printf( "%d\n", a );
    return 0;
}

The way your program seems to be written you probably will
expect that this program will print "7". But it doesn't, it
prints "3". That's because what the foo() function receives
is just the value 3, which gets stored in a variable named
'x' local to the foo() function. Modifying 'x' in foo() has
no effect at all on the value of 'a' in main()!

If you want to changed what's stored in 'a' by a call of
foo() you have to use a pointer. The program then would
look like this:

#include <stdio.h>

void foo( int * x ) {         /* function expects poiner to int */
    *x = 7;                   /* modify what's stored at that address */
}

int main( void ) {
    int a = 3;
    foo( &a );                /* pass a pointer to 'a' */
    printf( "%d\n", a );
    return 0;
}

Now foo() is able to modify what 'a' contains. That's because
it receives the address of 'a' (and not the value of what's
stored in 'a').

This is completely different from FORTRAN where everything is
passed by address (at least that's how it was when I learned
FORTRAN many years ago;-) Since the functions in FORTRAN
thus work directly on addresses all changes to arguments
made in a function also apply to the caller. But this isn't
how things work in C. In C you have to explicitely tell when
you want to pass an address instead of just a value, and you
have to explicitely assign to the address in the function!
(Well, arrays are a bit different, but since you don't seem
to use any I wont go into this...)

>      if ( count = limit)
>      A = -1;
>     else
>     {
>      ... Some more math..
>      }
>      return A;
>      }

>      void funcB (double A, int pF, int pN, int pD, double pC, double pB, double pA, double z)
>      {
>      z = (pow (A, pF) * (A - 1)) / (1 - (pow (A, -pN)));
>      z = pB / z;
>      z = z - pA - (pC / pow (A, pD));
>      }

>      void funcC (double A, int pF, int pN, int pD, int pC, double pB, double pa, double v, double w, double x, double y, double z)

>      {
>      A = some math...
>      calcz (A, pF, pN, pD, PC, pB, pA, z);
>      Some more math...
>      }

> The funcA is called by a Cobol program, and this C program compiles
> fine. But only during run time there's an error. The input is just 6
> values. pA, pB, pC, pD, pF, pN.

> If you see in funcC it calls funcB whose first line of code does a
> complex exponential calculation which overflows at some particular
> iteration, resulting in the range fault like I stated earlier.

It eems to me rather likely it;s due to the fact that all
the results computed in funcB() and funcC() are thrown away
the moment you leave these functions instead of appearing in
the caller. If you need them in the caller you have to either
return a value as the return value of the function (funcB()
looks like a candidate for that since you only seem to want
'z' as a result) or, if you need to get several values back
from a function call, by using pointers (a different way to
avoid the use of pointers would be the use of a structure as
a return value of the function).

> Inputs:

>       pA = 1000 pB = 44.50 pN = 25 pC = 0 pD = 2 pF = 2

> These are correct inputs for which program works fine. Only for a few
>  weird inputs passed, like below, it gives the range fault. 

>       pA = 1000
>       pB = 144.50
>       pN = 25
>       pC = 0
>       pD = 2
>       pF = 2

> I just need to catch this error in run time and tell the calling
> program that this is a bad input. I don't want the program to fail.
> Because it would cause the calling program to fail as well. Could this
> be accomplished in C itself?

Sorry, but you'll have to fix the primary problem first.
And then there's hardly any information on what really
happens in the program (pr what library you're using), so
it is impossible to tell why you get some "range fault"
under certain circumstances (and what's throwing it) as
well as how to avoid it.
                             Regards, Jens
-- 
  \   Jens Thoms Toerring  ___      jt@toerring.de
   \__________________________      http://toerring.de

[toc] | [prev] | [next] | [standalone]


#54739

FromShiva <subramanian.klu@gmail.com>
Date2014-12-16 11:33 -0800
Message-ID<079d80e9-04b3-4ea4-958a-72033e2c46e0@googlegroups.com>
In reply to#54651
Hi Jens, 

Thanks for your response. Really sorry about the code. I posted an earlier version. Really sorry, my bad. 

I've had corrected these and added the variables as globals. And I've had also passed the returns from functions into variables. Below is the corrected code (from memory) point me if it is wrong, but I got the functionality of fortran code replicated into the C code, of which I'm sure. 

Can you please answer the original question now that I got the right code? 

long long int pA, pB, pC, pD, pF, pN;
double z, A;

long long int funcA (long long int, long long int, long long int, long long int, long long int, long long int) 

    { 
    ... Initialisation... 

    z = funcB (A, pF, pN, pD, pC, pB, pA, z); 

    ...initialisations value assigning to other variables...A 


    z = funcB (A, pF, pN, pD, pC, pB, pA, z); 

    do 
    { 

     A = funcC (A, pF, pN, pD, pC, pB, pA, v, w, x, y, z); 

     count = count + 1; 

     } while (((z >= 0.0001) || (z <= 0.0001)) && count < limit); 

     if ( count = limit) 
     A = -1; 

    else 
    { 
     ... Some more math.. 
     } 
     return A; 
     } 


     double funcB (double A, int pF, int pN, int pD, double pC, double pB, double pA, double z) 

     { 

     z = (pow (A, pF) * (A - 1)) / (1 - (pow (A, -pN))); 

     z = pB / z; 
     z = z - pA - (pC / pow (A, pD)); 

    return (z);

     } 

     double funcC (double A, int pF, int pN, int pD, int pC, double pB, double pa, double v, double w, double x, double y, double z) 

     { 

     A = some math... 

     z = calcz (A, pF, pN, pD, PC, pB, pA, z); 

     Some more math... 

     return (A);
     } 



If you see the error that I have listed above - it says that the range fault occurs in funcB (I have debugged to the point that it is actually line one of funcB) It is trying to calculate the value for (1/10 ^ 72) or something like that. Can get you the exact value if you'd like. That's where it gives the range fault.

So as I mentioned it happens in line 1 of funcB when it is called by funcC, which is called by funcA which is called by some other COBOL program. 

Just want to catch this run time error. Not sure what you mean by libraries. 

I use STDIO.H, STDLIB.H and MATH.H nothing else. And the compiler I use is C89 version for Tandem HP NS product. 

[toc] | [prev] | [next] | [standalone]


#54764

FromBarry Schwarz <schwarzb@dqel.com>
Date2014-12-16 14:27 -0800
Message-ID<b1b19a9ursqsbbv7n5cbr8bdiup8e0tluq@4ax.com>
In reply to#54739
On Tue, 16 Dec 2014 11:33:05 -0800 (PST), Shiva
<subramanian.klu@gmail.com> wrote:

Please set your newsreader to limit your lines to less than 80
characters.

>Hi Jens, 
>
>Thanks for your response. Really sorry about the code. I posted an earlier version. Really sorry, my bad. 
>
>I've had corrected these and added the variables as globals. And I've had also passed the returns from functions into variables. 
>Below is the corrected code (from memory) point me if it is wrong, but I got the functionality of fortran code replicated into the C code, of which I'm sure. 
>
>Can you please answer the original question now that I got the right code?

But you don't have the right code yet. 

>long long int pA, pB, pC, pD, pF, pN;
>double z, A;

You should be aware that these variables are not used in any function
which has a parameter of the same name.

>
>long long int funcA (long long int, long long int, long long int, long long int, long long int, long long int) 

What are the names of these parameters?  How is this function called?

>
>    { 
>    ... Initialisation... 
>
>    z = funcB (A, pF, pN, pD, pC, pB, pA, z);

The second argument to funcB is a long long.
The seventh argument to funcB is a long long.
 
>
>    ...initialisations value assigning to other variables...A 
>
>
>    z = funcB (A, pF, pN, pD, pC, pB, pA, z); 
>
>    do 
>    { 
>
>     A = funcC (A, pF, pN, pD, pC, pB, pA, v, w, x, y, z); 
>
>     count = count + 1; 
>
>     } while (((z >= 0.0001) || (z <= 0.0001)) && count < limit); 

funcC tried to change z but the change was made to a different z than
the one tested here.  (The z that was changed was local to funcC and
no longer exists when your program evaluates the while expression.)

>     if ( count = limit) 
>     A = -1; 
>
>    else 
>    { 
>     ... Some more math.. 
>     } 
>     return A; 
>     } 
>
>
>     double funcB (double A, int pF, int pN, int pD, double pC, double pB, double pA, double z) 

The second argument passed to funcB is converted to an int to match
the parameter.  If the value of the long long argument is outside the
range [INT_MIN,INT_MAX], the behavior is undefined.  At the very
least, the parameter has the wrong value.

The seventh passed to funcB is converted to a double to match the
parameter.  This can easily result in the loss of significant digits
which may contribute to your problem.

>     { 
>
>     z = (pow (A, pF) * (A - 1)) / (1 - (pow (A, -pN))); 
>
>     z = pB / z; 
>     z = z - pA - (pC / pow (A, pD)); 
>
>    return (z);
>
>     } 
>
>     double funcC (double A, int pF, int pN, int pD, int pC, double pB, double pa, double v, double w, double x, double y, double z) 
>
>     { 
>
>     A = some math... 
>
>     z = calcz (A, pF, pN, pD, PC, pB, pA, z); 

z is changed but neither the global variable z nor the (assumed) z
local to funcA contain this new value.

>     Some more math... 
>
>     return (A);
>     } 
>
>
>
>If you see the error that I have listed above - it says that the range fault occurs in funcB (I have debugged to the point that it is 

Since the call to funcB is inside the broken do ... while, do you know
how many times it was called before the problem manifested itself?

>actually line one of funcB) It is trying to calculate the value for (1/10 ^ 72) or something like that. Can get you the exact value 
>if you'd like. That's where it gives the range fault.
>
>So as I mentioned it happens in line 1 of funcB when it is called by funcC, which is called by funcA which is called by some other COBOL program. 

The code you have given us does not show funcC calling funcB.

>Just want to catch this run time error. Not sure what you mean by libraries. 
>
>I use STDIO.H, STDLIB.H and MATH.H nothing else. And the compiler I use is C89 version for Tandem HP NS product. 

Those are not libraries; they are headers.  Headers are processed by
the compiler during compilation.  Libraries are processed after
compilation by the linker when the object modules are being combined
to form an executable program.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#54774

Fromjt@toerring.de (Jens Thoms Toerring)
Date2014-12-16 23:08 +0000
Message-ID<cfbsbnFmha3U1@mid.uni-berlin.de>
In reply to#54739
Shiva <subramanian.klu@gmail.com> wrote:
> Hi Jens, 

> Thanks for your response. Really sorry about the code. I posted an earlier
> version. Really sorry, my bad.

Nothing to be sorry about;-)

> I've had corrected these and added the variables as globals.

Now you have global variables and variables of the same names
as function argument names, which become local variables in
these functions, hiding the global variables. That, unfortu-
nately, doesn't solve the problem. If you do someting like

int a = 13;     // global variable

void foo( a ) {
    a = 42;
}

all you achive is creating two variables, one global named 'a'
and another one with the same name, only existing in foo().
And this local variable in foo() hides the global one in foo().

So, you either have to do everything via global variables (not
something I personally would recommend, but there can be situa-
tions where there's no better solution) or use the function
arguments how it's properly done in C/

> And I've had
> also passed the returns from functions into variables. Below is the
> corrected code (from memory)

It tends to be better to post the exact code...

> point me if it is wrong, but I got the
> functionality of fortran code replicated into the C code, of which I'm sure.

> Can you please answer the original question now that I got the right code? 

> long long int pA, pB, pC, pD, pF, pN;
> double z, A;

> long long int funcA (long long int, long long int, long long int, long long int, long long int, long long int) 

This obviously is either from memory, but incorrect (because
you need to give names to the variables in C) or you're using
a C++ compiler (in C++ it's, in contrast to C, allowed to
leave out the names for arguments not used in the function).

And where do these global variables get set? I have trouble
understanding what happens here. One guess is that there's some
other function calling funcA(), setting them up and then calling
funcA(). That might work. modulo the missing argument names, but
that's missing from you code. And you also mention something
about funcA() called from Cobol. Call me puzzled...

>     { 
>     ... Initialisation... 
>     z = funcB (A, pF, pN, pD, pC, pB, pA, z); 
>     ...initialisations value assigning to other variables...A 
>     z = funcB (A, pF, pN, pD, pC, pB, pA, z); 
>     do 
>     { 
>      A = funcC (A, pF, pN, pD, pC, pB, pA, v, w, x, y, z); 
>      count = count + 1; 
>      } while (((z >= 0.0001) || (z <= 0.0001)) && count < limit); 
>      if ( count = limit) 
>      A = -1; 
>     else 
>     { 
>      ... Some more math.. 
>      } 
>      return A; 
>      } 

>      double funcB (double A, int pF, int pN, int pD, double pC, double pB, double pA, double z) 

>      { 
>      z = (pow (A, pF) * (A - 1)) / (1 - (pow (A, -pN))); 
>      z = pB / z; 
>      z = z - pA - (pC / pow (A, pD)); 
>     return (z);
>      } 

>      double funcC (double A, int pF, int pN, int pD, int pC, double pB, double pa, double v, double w, double x, double y, double z) 
>      { 
>      A = some math... 
>      z = calcz (A, pF, pN, pD, PC, pB, pA, z); 
>      Some more math... 
>      return (A);
>      } 

> If you see the error that I have listed above - it says that the range fault
> occurs in funcB (I have debugged to the point that it is actually line one
> of funcB) It is trying to calculate the value for (1/10 ^ 72) or something
> like that. Can get you the exact value if you'd like. That's where it gives
> the range fault.

> So as I mentioned it happens in line 1 of funcB when it is called by funcC,
> which is called by funcA which is called by some other COBOL program.

> Just want to catch this run time error. Not sure what you mean by libraries. 

> I use STDIO.H, STDLIB.H and MATH.H nothing else. And the compiler I use is
> C89 version for Tandem HP NS product.

Never used that (which might explain my unfamilarity with the
wording of the error message you got). My only guess at the
moment is that with (1/10^72) a floating point exception is
raised (assuming that it comes from one of the pow() calls)
because the result would underflow on your machine. The name
"Tandem" evokes memories of old times and all Google searches
with "Tandem HP NS" come up with some machines from nearky
40 years ago;-) - is this perhaps some machine with 32-bit
floating point numbers? In that case (as- suming IEEE-754
floating point representation) the range for floating point
numbers is in that case is somewhere 10^38 and 10^-38. Thus
(1/10^72) would underflow. That's still within the requirements
by C89 - the smallest double don't have to be smaller than
10^-37.

I'd try to simply print out the value of the nacro DBL_MIN from
<limits.h> to check if this what's going on your machine.

If that's the case the obvious question is how to avoid the
problem. Unfortunately, the C89 standard only says about the
pow() function that "A range error may occur.". It's not speci-
fied what exact effects that may have. It's not unheard of that
for underflows a floating-point exception (FE_UNDERFLOW) is
raised. That can depend, as far as I know, on settings for
the programs not defined in the C89 standard (C99 added some
support for this). My guess is that your best bet is to trya
avoiding calling pow() with values that might under/overflow
if possible. Or try to find out how to disable that such floa-
ting point exceptions get raised, kiling your program, under
these circumstances on your system (returning just 0 as the
result) - but that's something I definitely can't help with,
knowing nothing about that system, sorry.

                           Regards, Jens
-- 
  \   Jens Thoms Toerring  ___      jt@toerring.de
   \__________________________      http://toerring.de

[toc] | [prev] | [next] | [standalone]


#54779

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2014-12-16 23:44 +0000
Message-ID<87h9wv40st.fsf@bsb.me.uk>
In reply to#54739
Shiva <subramanian.klu@gmail.com> writes:
<snip>
> I've had corrected these and added the variables as globals. And I've
> had also passed the returns from functions into variables. Below is
> the corrected code (from memory) point me if it is wrong, but I got
> the functionality of fortran code replicated into the C code, of which
> I'm sure.
>
> Can you please answer the original question now that I got the right
> code? 

Your code is very odd what makes it hard to believe that you really
wanted to write what you've posted.  What's more, you code is not
syntactically correct because you are posting some approximation of the
real code.  Please, post the real code.  There may be other errors that
are affecting what you see, and I may be commenting on errors that are
not in the real code...

> long long int pA, pB, pC, pD, pF, pN;
> double z, A;
>
> long long int funcA (long long int, long long int, long long int, long
> long int, long long int, long long int)
>
>     { 
>     ... Initialisation... 
>
>     z = funcB (A, pF, pN, pD, pC, pB, pA, z); 
>
>     ...initialisations value assigning to other variables...A 
>
>
>     z = funcB (A, pF, pN, pD, pC, pB, pA, z); 
>
>     do 
>     { 
>
>      A = funcC (A, pF, pN, pD, pC, pB, pA, v, w, x, y, z); 
>
>      count = count + 1; 
>
>      } while (((z >= 0.0001) || (z <= 0.0001)) && count < limit); 

This is very odd.  Do you know what a NaN is?  Only of z is a NaN will
the test on z be anything but true so it's probably pointless.  What's
more, the body of the loop can't change z so testing it in the loop
condition is just bizarre.  You don't show or say how count is
initialised, but if it starts at something sensible (zero, say) then, in
the absence of NaNs, this loop terminates when count == limit.

>      if ( count = limit) 

This is an assignment and sets, rather than tests, count.  Did you mean
count == limit?

>      A = -1; 
>
>     else 
>     { 
>      ... Some more math.. 
>      } 
>      return A; 
>      } 
>
>
>      double funcB (double A, int pF, int pN, int pD, double pC, double pB, double pA, double z) 
>
>      { 

This function does not use z so it should not be a parameter.  Why are
the globals declared long long int and these parameters int?  Is that
correct?  Is there a prototype for this function in scope in the loop
above?  If not, you have another problem.  (Just ask if you don't know
what I mean by this.)

>      z = (pow (A, pF) * (A - 1)) / (1 - (pow (A, -pN))); 
>
>      z = pB / z; 
>      z = z - pA - (pC / pow (A, pD)); 
>
>     return (z);
>
>      } 
<snip>
> If you see the error that I have listed above - it says that the range
> fault occurs in funcB (I have debugged to the point that it is
> actually line one of funcB) It is trying to calculate the value for
> (1/10 ^ 72) or something like that. Can get you the exact value if
> you'd like. That's where it gives the range fault.

This is the least interesting fault in the program!  A range error just
means that the pow function overflows or underflow and that just means
the some out-of-range values get passed.  The solution is not to pass
values that cause the out-of-range result or to test that this has
happened.

> So as I mentioned it happens in line 1 of funcB when it is called by
> funcC, which is called by funcA which is called by some other COBOL
> program.

Please post the real code and an example of a call (i.e. what values get
passed to funcA).

> Just want to catch this run time error. Not sure what you mean by
> libraries. 

The general technique is to:

(a) include errno.h
(b) set errno = 0 before the function call in question (here, pow)
(c) test for errno == ERANGE after the call.

> I use STDIO.H, STDLIB.H and MATH.H nothing else. And the compiler I
> use is C89 version for Tandem HP NS product.

It's stdio.h, stdlib.h and math.h (and now you need errno.h) but that
compiler is an antique.  That only matters because C89 does not have
long long int so you may be using some odd compiler extension.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#54741

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-12-16 19:37 +0000
Message-ID<m6q1m6$jh6$1@speranza.aioe.org>
In reply to#54651
Jens Thoms Toerring <jt@toerring.de> wrote:

(snip)

> Now foo() is able to modify what 'a' contains. That's because
> it receives the address of 'a' (and not the value of what's
> stored in 'a').
 
> This is completely different from FORTRAN where everything is
> passed by address (at least that's how it was when I learned
> FORTRAN many years ago;-) Since the functions in FORTRAN
> thus work directly on addresses all changes to arguments
> made in a function also apply to the caller. But this isn't
> how things work in C. In C you have to explicitely tell when
> you want to pass an address instead of just a value, and you
> have to explicitely assign to the address in the function!
> (Well, arrays are a bit different, but since you don't seem
> to use any I wont go into this...)

Fortran doesn't require pass by address (often called reference).
It also allows for call by value result, sometimes called copy-in
copy-out.  As far as I know, it has always been that way.

The OS/360 Fortran compilers copy scalars to local variables,
and copy them back before return.

-- glen

[toc] | [prev] | [next] | [standalone]


#54784

Fromjt@toerring.de (Jens Thoms Toerring)
Date2014-12-17 00:12 +0000
Message-ID<cfc030Fn3o1U1@mid.uni-berlin.de>
In reply to#54741
glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
> Jens Thoms Toerring <jt@toerring.de> wrote:

> (snip)

> > Now foo() is able to modify what 'a' contains. That's because
> > it receives the address of 'a' (and not the value of what's
> > stored in 'a').
>  
> > This is completely different from FORTRAN where everything is
> > passed by address (at least that's how it was when I learned
> > FORTRAN many years ago;-) Since the functions in FORTRAN
> > thus work directly on addresses all changes to arguments
> > made in a function also apply to the caller. But this isn't
> > how things work in C. In C you have to explicitely tell when
> > you want to pass an address instead of just a value, and you
> > have to explicitely assign to the address in the function!
> > (Well, arrays are a bit different, but since you don't seem
> > to use any I wont go into this...)

> Fortran doesn't require pass by address (often called reference).

Thanks, that was exactly the term I as was looking for;-)

> It also allows for call by value result, sometimes called copy-in
> copy-out.  As far as I know, it has always been that way.

As I wrote I learned a bit of FORTRAN as my very first pro-
gramming language more than a quarter of a century ago, when
it was still called FORTRAN 77. And I haven't had much expo-
sure to it in the last decades, so I probably mis-remember a
lot;-) I just remember that I learned that there's something
else than "passing by reference" when I learned Pascal, and
the "FORTRAN always passes by reference" has somehow stuck.
Having to deal with a few cases of interfacing C and FORTRAN
code and having to pass pointers to the FORTRAN functions
called from C probably fortified that idee.

                        Best regards, Jens
-- 
  \   Jens Thoms Toerring  ___      jt@toerring.de
   \__________________________      http://toerring.de

[toc] | [prev] | [next] | [standalone]


#54881

FromShiva <subramanian.klu@gmail.com>
Date2014-12-17 13:05 -0800
Message-ID<e3eb318e-355d-411b-8215-f2f022485b08@googlegroups.com>
In reply to#54784
Hi all,

Thanks for your immediate responses and valuable answers. It seems that the above code I posted from memory (hell let lose) is wrong. There were so many reasons why I did not post the exact code before. Some reasons I can't state here. But I am doing so now, please find the correct code below. Any faults in the below program are possibly typo. My confidence in saying that the below code is right, is from experience. The code works for the correct inputs. It just fails when the wrong input is provided and that's where I want to correct the code.

Code: 

  double A,v,w,x,y,z;
  double funcC (int, int, int, double, double, double);
  double funcB (int, int, int, double, double, double);
  long int funcA (long long int Lp1, long long int Lp2, long long int Lp3, long long int Lp4  , long long int Lp5, long long int Lp6) 

    { 
    
     double pA, pB, pC;
     int pD, pF, pN, count, limit;
     long int r;
     double q;
     pA = (double) Lp1/100;
     pB = (double) Lp2/100;
     pC = (double) Lp3/100;
     pD = Lp4;
     pF = Lp5;
     pN = Lp6;
     limit = 100;
     q = pow (10,7);
     A = 10000001/q;
     z = funcB (pF, pN, pD, pC, pB, pA);
     v = A;
     w = z;
     A = 1.05;
     z = funcB (pF, pN, pD, pC, pB, pA);
     x = A;
     y = z;
     count = 0;
     do
      { 
        A = fuc (pF, pN, pD, pC, pB, pA);
        count = count + 1;
       } while ((( z > = 0.0001) || ( z <= -0.0001)) && (count < limit));
      if ( count == limit)
      A = -1;
      else
      A = (pow (A, 12) - 1) * 100; 
      A = (double) ((long long int) (( A + 0.005) * 100 )) / 100;
      }
      A = A * 1000;
      r = (long int) A;
      return (r);
  }
   

double funcB (int pF, int pN, int pD, double pC, double pB, double pA) 

{ 
  double F1, F2; 
  F1 = pow (ACY, -parmN); 
  F2 = pow (ACY, parmF); 
  z = ((F2 * ACY - 1) ) / (1 - F1));
  z = pB/ z;
  z = z - pA - (pC/ pow (ACY, pD));
  return (z);
}


  double funcC (int pF, int pN, int pD, double pC, double pB, double pA) 
   { 
      double a,b,c,d,e;
      a = x - v; 
      b = w - y;  
      A = V + (fabs(w)/ ((fabs(b)) / (a)));
      z = funcB (pF, pN, pD, PC, pB, pA); 
     if (z > 0) 
     { 
     v = A; 
     w = z; 
     } else if (z < 0) 
     { 
     x = A ;  
     y = z; 
     } 
     return (A); 
     } 


Not using a C++ compiler. Just using the C89 compiler. Of that I'm sure. Will try some C++ code and try to execute using the same compiler tomorrow, just to be double sure.

-- I'd try to simply print out the value of the nacro DBL_MIN from 
-- <limits.h> to check if this what's going on your machine. 

I'd try the above also tomorrow.

Also just to state it clear the source file has only the above code. And it is compiled. funcB and funcC are local here. (by local I mean, not used anywhere else outside this source file) But the funcA is called by the Cobol program who passes the input values onto the funcA. Those six Lp1, Lp2, etc.

And somebody mentioned NaN on seeing the while condition for z. I'm not sure what NaN is.

And this: 

The general technique is to: 

(a) include errno.h 
(b) set errno = 0 before the function call in question (here, pow) 
(c) test for errno == ERANGE after the call. 

====

Now that I've posted the correct code, can you please point me to where should I add the above and how? I saw the errno.h file. It had indicators for range faults as well. And arithmetic faults. This should fall under one of them for sure. 

Really sorry about the wrong versions of the code. My bad. Some restrictions as well.

Below is the correct input that's usually passed into the program. (correct input)

Lp1 = 1000000;
Lp2 = 25000;
Lp3 = 2;
Lp4 = 60;
Lp5 = 0;
Lp6 = 0;

For which the A value comes around 17.something which is right. 

Below is the bad input for which the code does not stumble, but picks out the correct error catch - setting A to -1 ...

Lp1 = 1759672;
Lp2 = 23306;
Lp3 = 2;
Lp4 = 60;
Lp5 = 0;
Lp6 = 0;

Another example.

Lp1 = 1636100;
Lp2 = 13844;
Lp3 = 2;
Lp4 = 60;
Lp5 = 0;
Lp6 = 0;

Because for the above two bad inputs, the count reaches the limit (100) set in the program and sets the -1 value for A back to the calling COBOL program.

Now the following is really bad input for which the code fails, unable to handle the range fault.

Lp1 = 200000;
Lp2 = 7345;
Lp3 = 2;
Lp4 = 12;
Lp5 = 0;
Lp6 = 0;

The above input when reaching count 66, produces the following value for F1;

F1 = 2.189569 e -77

So at the 67th count, when it goes to funcC who calls funcB at line 5 of it's function - the first calculation of funcB is F1 where this time it hits a value far below the previous one. And it fails. 

I've debugged the code, I've put in displays, introduced main () to print these outputs and so much more. I can find this really bad input even before passing onto funcC who passes it onto funcB - but I don't want to be the judge of that. I want the program to decide whether the range fault occurs and if so, then let the calling program know that the input is bad - by setting the value of A as -1, just like the other bad inputs do.

Hope I've made myself clear now.

[toc] | [prev] | [next] | [standalone]


#54891

FromBarry Schwarz <schwarzb@dqel.com>
Date2014-12-17 15:06 -0800
Message-ID<cn049alo4s068v3r5pntdbp9a27bliogd0@4ax.com>
In reply to#54881
On Wed, 17 Dec 2014 13:05:18 -0800 (PST), Shiva
<subramanian.klu@gmail.com> wrote:

>Hi all,
>
>Thanks for your immediate responses and valuable answers. It seems that the above code I posted from memory 
>(hell let lose) is wrong. There were so many reasons why I did not post the exact code before. Some reasons I 
>can't state here. But I am doing so now, please find the correct code below. Any faults in the below program are possibly 
>typo. My confidence in saying that the below code is right, is from experience. The code works for the correct inputs. 
>It just fails when the wrong input is provided and that's where I want to correct the code.

You should not be retyping your code.  It introduces too many errors
and we can't tell whether the problem is with your code or the typing.
Use cut and paste.  

>Code: 

Badly broken as posted.

>  double A,v,w,x,y,z;
>  double funcC (int, int, int, double, double, double);
>  double funcB (int, int, int, double, double, double);
>  long int funcA (long long int Lp1, long long int Lp2, long long int Lp3, long long int Lp4  , long long int Lp5, long long int Lp6) 
>
>    { 

<snip>

>     do
>      { 
>        A = fuc (pF, pN, pD, pC, pB, pA);

I assume you meant funcC here.

>        count = count + 1;
>       } while ((( z > = 0.0001) || ( z <= -0.0001)) && (count < limit));

Did you mean z >= 0.0001>

<snip>

>      }

This brace terminates funcA.  Since you still have code that is
obviously part of funcA, is this } a typo or is there a missing {?

>      A = A * 1000;
>      r = (long int) A;
>      return (r);
>  }
>   
>
>double funcB (int pF, int pN, int pD, double pC, double pB, double pA) 
>
>{ 
>  double F1, F2; 
>  F1 = pow (ACY, -parmN); 
>  F2 = pow (ACY, parmF); 
>  z = ((F2 * ACY - 1) ) / (1 - F1));
>  z = pB/ z;
>  z = z - pA - (pC/ pow (ACY, pD));
>  return (z);
>}
>
>
>  double funcC (int pF, int pN, int pD, double pC, double pB, double pA) 
>   { 
>      double a,b,c,d,e;
>      a = x - v; 
>      b = w - y;  
>      A = V + (fabs(w)/ ((fabs(b)) / (a)));

There is no V declared in scope.  C is case sensitive.  Did you mean
v?

>      z = funcB (pF, pN, pD, PC, pB, pA); 

There is no PC declared in scope.  C is case sensitive.  Did you mean
pC?

>     if (z > 0) 
>     { 
>     v = A; 
>     w = z; 
>     } else if (z < 0) 
>     { 
>     x = A ;  
>     y = z; 
>     } 
>     return (A); 
>     } 
>
>
>Not using a C++ compiler. Just using the C89 compiler. Of that I'm sure. Will try some C++ code and try to 
>execute using the same compiler tomorrow, just to be double sure.

I recommend not wasting your time changing languages until you get the
C code correct?

>-- I'd try to simply print out the value of the nacro DBL_MIN from 
>-- <limits.h> to check if this what's going on your machine. 
>
>I'd try the above also tomorrow.
>
>Also just to state it clear the source file has only the above code. And it is compiled. funcB and funcC are local here. (by 
>local I mean, not used anywhere else outside this source file) But the funcA is called by the Cobol program who passes 
>the input values onto the funcA. Those six Lp1, Lp2, etc.
>
>And somebody mentioned NaN on seeing the while condition for z. I'm not sure what NaN is.
>
>And this: 
>
>The general technique is to: 
>
>(a) include errno.h 
>(b) set errno = 0 before the function call in question (here, pow) 
>(c) test for errno == ERANGE after the call. 
>
>====
>
>Now that I've posted the correct code, 

No you haven't.

>can you please point me to where should I add the above and how? 

Near the top of your source file, add the following to your #include
statements:
    #include <errno.h>
Define a global int called my_error_flag.  It will be initialized by
default to 0.
Immediately after each statement that calls the pow function, insert:
    if (errno != 0) my_error_flag++;
At the appropriate point(s) in your code, test my_error_flag.  When it
is not 0, set A to -1.  You might also want to print out some
debugging data such as the value of my_error_flag and other variables
of interest.

>I saw the errno.h file. It had indicators for range faults as well. And arithmetic faults. This should fall under one of them for sure. 

Possibly but we won't be able to tell until you provide the correct
code.


-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#54893

FromRichard Heathfield <invalid@see.sig.invalid>
Date2014-12-17 23:15 +0000
Message-ID<x8okw.86550$P42.76665@fx24.am4>
In reply to#54891
Barry Schwarz wrote:

<snip>
 
> You should not be retyping your code.  It introduces too many errors
> and we can't tell whether the problem is with your code or the typing.
> Use cut and paste.

Better still, use *copy* and paste. :-)
 
<snip>

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#54899

FromKeith Thompson <kst-u@mib.org>
Date2014-12-17 16:00 -0800
Message-ID<ln61d9esi7.fsf@nuthaus.mib.org>
In reply to#54893
Richard Heathfield <invalid@see.sig.invalid> writes:
> Barry Schwarz wrote:
> <snip>
>  
>> You should not be retyping your code.  It introduces too many errors
>> and we can't tell whether the problem is with your code or the typing.
>> Use cut and paste.
>
> Better still, use *copy* and paste. :-)
>  
> <snip>

Great minds think alike.

And so do ours.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#54898

FromKeith Thompson <kst-u@mib.org>
Date2014-12-17 15:56 -0800
Message-ID<lna92lesom.fsf@nuthaus.mib.org>
In reply to#54891
Barry Schwarz <schwarzb@dqel.com> writes:
[...]
> You should not be retyping your code.  It introduces too many errors
> and we can't tell whether the problem is with your code or the typing.
> Use cut and paste.  
[...]

Probably a good idea if the code is worthless, but in most cases
copy-and-paste will work better.  8-)}

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#54993

FromShiva <subramanian.klu@gmail.com>
Date2014-12-18 12:28 -0800
Message-ID<f356152d-b545-4329-a765-68ea430cd83a@googlegroups.com>
In reply to#54891
#include<stdio.h>

#include<stdlib.h>

#include<math.h>

double A,v,w,x,y,z; 

double funcC (int, int, int, double, double, double); 

double funcB (int, int, int, double, double, double); 

long int funcA (long long int Lp1, long long int Lp2, long long int Lp3, long long int Lp4  , long long int Lp5, long long int Lp6) 

{
 
double pA, pB, pC; 

int pD, pF, pN, count, limit; 
     
long int r; 
     
double q; 
     
pA = (double) Lp1/100; 
     
pB = (double) Lp2/100; 
     
pC = (double) Lp3/100; 
     
pD = Lp4; 
     
pF = Lp5; 
     
pN = Lp6; 
     
limit = 100; 
     
q = pow (10,7); 
     
A = 10000001/q; 
     
z = funcB (pF, pN, pD, pC, pB, pA); 
     
v = A; 
     
w = z; 
     
A = 1.05; 
     
z = funcB (pF, pN, pD, pC, pB, pA); 
     
x = A; 
     
y = z; 
     
count = 0; 
     
do 
      
{ 
        
A = funcC (pF, pN, pD, pC, pB, pA); 
        
count = count + 1; 
       
} while ((( z > = 0.0001) || ( z <= -0.0001)) && (count < limit)); 
      
if ( count == limit) 
      
A = -1; 
      
else 

{
      
A = (pow (A, 12) - 1) * 100; 
      
A = (double) ((long long int) (( A + 0.005) * 100 )) / 100; 
      
} 
      
A = A * 1000; 
      
r = (long int) A; 
      
return (r); 
  
} 
    

double funcB (int pF, int pN, int pD, double pC, double pB, double pA) 

{ 
  
double F1, F2; 
  
F1 = pow (A, -pN); 
  
F2 = pow (A, pF); 
  
z = ((F2 * (A - 1) ) / (1 - F1)); 
  
z = pB/ z; 
  
z = z - pA - (pC/ pow (A, pD)); 
  
return (z); 
} 

double funcC (int pF, int pN, int pD, double pC, double pB, double pA) 
   
{ 
      
double a,b,c,d,e; 
      
a = x - v; 
      
b = w - y;   
      
A = v + (fabs(w)/ ((fabs(b)) / (a))); 
      
z = funcB (pF, pN, pD, pC, pB, pA); 
     
if (z > 0) 

{ 

v = A; 

w = z; 

} 

else if (z < 0) 

{ 

x = A ;   

y = z; 

} 

return (A); 

} 

Hi, the above code is devoid of the following errors which were mentioned.

1) A } closed funcA before it closed. - Missing { in else part. Added that.
2) It was not fuc. It was indeed funcC, typo, sorry. Changed that.
3) Not caps V. Again, my bad. Sorry changed that. And not PC, it is pC. Sorry.
4) ACY, parmN, parmF were not defined. They were A, pN, pF. Sorry again.
5) One too many ) on funcB line 4. There was actually a ( missing. Added that.

And Jen and Barry, your remaining queries answered below: 

Did you mean z >= 0.0001> 
Didn't understand this point.

 ---- 
This could more easily written as 'q = 1e7;'. 
Yeah, I know. Didn't want to deviate from the look of the fortran code as much as possible. Part of the requirement. :)
-----
None of the variables 'A', 'z', 'v' or 'w' are defined in your 
program. And 'w' and 'w' are never agin used in this function. 
Are they global variables for which you haven't show the the 
source lines? 
They are mentioned in the first line of the code, mate. :)They were there in the previous version even. Think may be you missed it.
---
You're never changing 'z' in this loop. So the loop will either 
be run just once (if 'z' you started with is not in the interval 
[-1e-4,1e-4]) or it will be run exacty 'limit' times. 
The value of 'z' gets changed in the loop of course. The main point of that condition is that the limit should never be reached, and if it does - it does so only for 'bad' inputs. 100% sure of that.
---
        A = 0.01 * floor( 100 * A + 0.5 ); 

Note that this (as your method) may not be what you want should 
'A' ever be negative... 

A will never be negative. For the right inputs. For the bad inputs, A can be negative and in that case the limit will be reached and this line will never be processed. So we're saved there. 

But yes, your line of code is good. Again, just wanted to resemble the fortran code as much as I could. Part of the requirement, again. :)

But for your comfort, going to let you in on a little secret.. these math calculations were made up by a very well known maths doctorate from Harvard. Pretty sure he got his math right. So now you know where my 100% sureity comes from. :D
-----
What about the case that 'z' is exactly 0? 
Again, if z was zero it would never come up to that loop into that function now, would it -remember the while condition. :)


So the error comes up in funcB line:

F1 = pow (A, -pN); 

where F1's value in the 66th iteration becomes 2.189569 e -77already and hence will try to become more lesser in the 67th iteration and that's where it fails.

This funcB is called in the funcC line: 

z = funcB (pF, pN, pD, pC, pB, pA); 

And the input values can be divided into three types. Good (working), bad (still working, but returns A value as -1 to cobol), and really bad inputs. (which abends at run time)

So the really bad input which causes the run time abend is the following: 

Lp1 = 200000; 
Lp2 = 7345; 
Lp3 = 2; 
Lp4 = 12; 
Lp5 = 0; 
Lp6 = 0; 

But the code is able to return the value of A as -1 to cobol (as error catched through the limit count) for the following bad input: 

Lp1 = 1759672; 
Lp2 = 23306; 
Lp3 = 2; 
Lp4 = 60; 
Lp5 = 0; 
Lp6 = 0; 

Another example. 

Lp1 = 1636100; 
Lp2 = 13844; 
Lp3 = 2; 
Lp4 = 60; 
Lp5 = 0; 
Lp6 = 0; 

And the example for right input are 

Lp1 = 1000000; 
Lp2 = 25000; 
Lp3 = 2; 
Lp4 = 60; 
Lp5 = 0; 
Lp6 = 0; 

For which the A value comes around 17.something which is right. 

I just want to stop the abend from happening for the really bad input that I've mentioned first in the series and return the same -1 value to COBOL for A, just like how it does for other bad inputs.

Like I said all those where my mistakes, typos which I mentioned might have occurred. I hope I've cleared all the errors in the above code. I'm really sorry that I've just re-typed it though you all have clearly mentioned that I should not do that. I don't have an option. I would have gladly copy pasted the code in a blink, if I had the chance. I hope you understand. 

And if you want to compile the above code with displays and show it to your terminal, I believe you'll need a main() for that. But I guess you can write that up. Just need to pass the Lp1, Lp2, Lp3, Lp4, Lp5, Lp6 to the funcA and call it. 

Hope somebody can help me out now. Thanks a lot for all your comments already. Really appreciated. :)

[toc] | [prev] | [next] | [standalone]


#55006

FromBarry Schwarz <schwarzb@dqel.com>
Date2014-12-18 14:07 -0800
Message-ID<32j69a53cuiij36o632up2ts6nvlkk016q@4ax.com>
In reply to#54993
On Thu, 18 Dec 2014 12:28:42 -0800 (PST), Shiva
<subramanian.klu@gmail.com> wrote:

>Did you mean z >= 0.0001> 
>Didn't understand this point.

Your previous code and this code both contain the phrase
     z > = 0.0001
with a space between the > and the =.  This is a syntax error.

Oddly enough, you didn't have the same problem with 
     z <= -0.0001
on the same line.

Even if you cannot post your actual code, you could at least compile
what you do post before posting it to get rid of the typos.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#55010

FromBarry Schwarz <schwarzb@dqel.com>
Date2014-12-18 14:16 -0800
Message-ID<8qj69apnkdurf01kec1fun6hoj8uardush@4ax.com>
In reply to#54993
On Thu, 18 Dec 2014 12:28:42 -0800 (PST), Shiva
<subramanian.klu@gmail.com> wrote:

>long int funcA (long long int Lp1, long long int Lp2, long long int Lp3, long long int Lp4  , long long int Lp5, long long int Lp6) 
>{

Your input specifies that Lp5 and Lp6 are both 0.

<snip>
>pF = Lp5; 
>pN = Lp6; 

Obviously variables pF and pN are both 0.

<snip>
>z = funcB (pF, pN, pD, pC, pB, pA); 
<snip>
>} 
>
>double funcB (int pF, int pN, int pD, double pC, double pB, double pA) 
>{ 

Obviously parameters pF and pN are both 0.

>double F1, F2; 
>F1 = pow (A, -pN); 
>F2 = pow (A, pF); 

Obviously F1 and F2 are both 1.

>z = ((F2 * (A - 1) ) / (1 - F1)); 

And your divisor is now 0.  Dividing by 0 is not a task for the faint
of heart.
<snip>
>return (z); 
>} 
<snip>
>So the really bad input which causes the run time abend is the following: 
>
>Lp1 = 200000; 
>Lp2 = 7345; 
>Lp3 = 2; 
>Lp4 = 12; 
>Lp5 = 0; 
>Lp6 = 0; 
<snip>

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#55019

Fromjacob navia <jacob@spamsink.net>
Date2014-12-19 00:55 +0100
Message-ID<m6vph0$rd2$1@speranza.aioe.org>
In reply to#54993
Le 18/12/2014 21:28, Shiva a écrit :
> So the error comes up in funcB line:
>
> F1 = pow (A, -pN);
>
> where F1's value in the 66th iteration becomes 2.189569 e -77already and hence will

try to become more lesser in the 67th iteration and that's where it fails.

Undeflow/overflow is happening.

So, if pow(A,-pN) must be less than DBL_MAX or DBL_MIN, you can test for it

DBL_MAX 1.7976931348623157E+308

log (DBL_MAX) --> 709.78271289338399672769243071670056098

so if fabs(log(A)*log(pN)) > 700.0

this will overflow and

DBL_MIN 2.2250738585072014E-308

log(DBL_MIN) -708.39641853226410621681158499121371867

so if fabs(log(A)*log(pN)) > 700.0

will work also avoiding underflow.

I hope this is right. I *think* the reasoning is right but let's see 
what the other experts think here

[toc] | [prev] | [next] | [standalone]


#55021

Fromjt@toerring.de (Jens Thoms Toerring)
Date2014-12-19 00:18 +0000
Message-ID<cfh969F4bg7U1@mid.uni-berlin.de>
In reply to#54993
Shiva <subramanian.klu@gmail.com> wrote:

<working code snipped;-)>

Sorry to hear about your rather atrocious sounding working
conditions! Sounds like having a fist fight with both arms
tied to your back;-) So no appologies required for any pro-
blems with the code you post.

While your program now compiles, it doesn't behave for me as
you describe it. And Barry already pointed out that it can't
work properly, even with your "good" inputs. Thus I suspect
that there's still are some deviations from what you used in
your own tests. But the problem you want to solve, as far as
I understand, is not really about the code and it's behaviour
and results, but just how to keep the program from crashing.

To be honest, I don't know. But let me mention a few points
anyway that might help point you in the right direction (my
explanation might be a bit flawed, but I hope that others
with more experience in these matters will chime in and
correct my mistakes):

If the pow() function is called this invokes some function
in the math library. If you have some kind of "floating point
unit" (FPU) on your machine (nowadays part of the CPU, in the
olden days often an additional chip) the math library will send
the arguments to the FPU and instruct it to do the required
calculations.

Now, if the FPU notices that the arguments are unsuitable
or the result would over- or underflow what can be repre-
sented by a floating point number it raises some kind of
"exceptition" (there can be different types for different
error conditions).

The math library now can either "catch" that exception or
pass it on to the caller. If it's set up to catch these
exceptions it will return some kind of result (that may
include 'Inf' or 'NaN', 0, HUGE_VAL etc.) and set 'errno'
appropriately. The caller then can check the return value
and 'errno' to detect possible problems.

If the math library isn't set up to "catch" the exception
the caller may try to do that itself. If he doesn't it may
result in the program aborting. That seems to be what you
are experiencing.

If this is what happens you have, as far as I can see at
the moment, three possibilities:

a) Ensure that the math library catches the errors and
   then deal with cases where 'errno' indicates that
   something went wrong.
b) Catch the floating point exception yourself and deal
   with it in some suitable way (or perhaps set your
   system up to ignore these floating point exceptions -
   but that might result in invalid final results).
c) Check what you're going to pass to pow() and don't call
   it when there's something that might upset the FPU.

The problem is that none of them are simple to implement
and may need some good knowledge about the system and
conpiler you're using, And I never heard of the "Tandem"
system you're working on, what the compiler, the OS or the
CPU architecture migth be.

Possible problems I see at the moment:

a) On all systems I normally have to deal with the math
   library is per default set up to catch floating
   point exceptions. Something must be different on your
   system - perhaps the COBOL program your functions are
   invoked from is doing that. If not, making sure the
   exceptions get caught could involve certain compiler
   flags, arguments to the program or environment vari-
   ables set in a certain way. Otherwise system-specific
   functions may have to be called (which undo the changes
   the COBOL part of the program may have made and perhaps
   also reset stuff back to the previous state when done
   with the C part, so the COBOL part still works as
   before).
b) Catching the floating point exception yourself also
   requires system-specific methods. E.g. on Unix you'd
   have to catch a SIGFPE signal. But this probably will
   be quite different on other operating systems.
c) Vetting the arguments before calling pow() can be quite
   some task - if done 100% correct it might require to write
   some kind of pow() function yourself. But if it's only
   about catching invalid input that might be simpler:
    * catch 0 as the base argument with any negative exponents
    * catch a negative base with anything but odd integer
      exponents
   A conservative ballpark check for over- and underflows
   is also possible but takes some thinking about to get
   right (and to be not too convervative). Let me know if
   you want to go down that road and need help with it. Of
   course this won't speed up the program at all;-(

                     Best regards, Jens
-- 
  \   Jens Thoms Toerring  ___      jt@toerring.de
   \__________________________      http://toerring.de

[toc] | [prev] | [next] | [standalone]


#55024

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2014-12-19 01:12 +0000
Message-ID<87bnn0wihe.fsf@bsb.me.uk>
In reply to#54993
Shiva <subramanian.klu@gmail.com> writes:

I'm going to "cut to the chase" despite a very strong feeling that your
first step should be to re-write the code that it stands a chance of
being understood.  I don't know how you can be sure it is doing what you
want, but let's put that to one side.

<snip>
> So the really bad input which causes the run time abend is the
> following: 

'abend' is a term I've not heard in decades!  It suggests to me that
your run-time is generating some signal or arithmetic exception.  If
this is so, your either have to to catch and handle it, or you must
prevent it happening to start with.

If you are *not* getting a signal (or exception -- the terminology
varies) and the problem is, as you think, in the pow function, then you
can use the method of setting and testing errno which has already been
suggested.

If you have to catch and handle the signal you will have to say a whole
lot more about the system you are using.

If you want to try to prevent the fault before it happens, consider
re-writing the pow function using exp and log (and a multiplication).
This can help because it's easier to test for over- or underflow before
a call to these two one-argument functions than it is to test the
conditions under which pow will over- or underflow.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#54904

Fromjt@toerring.de (Jens Thoms Toerring)
Date2014-12-18 01:00 +0000
Message-ID<cfen9eFeib6U1@mid.uni-berlin.de>
In reply to#54881
Shiva <subramanian.klu@gmail.com> wrote:
> Hi all,

> Thanks for your immediate responses and valuable answers. It seems that the
> above code I posted from memory (hell let lose) is wrong. There were so many
> reasons why I did not post the exact code before. Some reasons I can't state
> here. But I am doing so now, please find the correct code below. Any faults
> in the below program are possibly typo. My confidence in saying that the
> below code is right, is from experience. The code works for the correct
> inputs. It just fails when the wrong input is provided and that's where I
> want to correct the code.

I'd love to try your code but there are still too many issues

> Code: 

>   double A,v,w,x,y,z;
>   double funcC (int, int, int, double, double, double);
>   double funcB (int, int, int, double, double, double);
>   long int funcA (long long int Lp1, long long int Lp2, long long int Lp3, long long int Lp4  , long long int Lp5, long long int Lp6) 
>     { 
>      double pA, pB, pC;
>      int pD, pF, pN, count, limit;
>      long int r;
>      double q;
>      pA = (double) Lp1/100;
>      pB = (double) Lp2/100;
>      pC = (double) Lp3/100;
>      pD = Lp4;
>      pF = Lp5;
>      pN = Lp6;
>      limit = 100;
>      q = pow (10,7);

This could more easily written as 'q = 1e7;'.

>       A = 10000001/q;
>      z = funcB (pF, pN, pD, pC, pB, pA);
>      v = A;
>      w = z;

None of the variables 'A', 'z', 'v' or 'w' are defined in your
program. And 'w' and 'w' are never agin used in this function.
Are they global variables for which you haven't show the the
source lines?

>      A = 1.05;
>      z = funcB (pF, pN, pD, pC, pB, pA);
>      x = A;
>      y = z;

There's also no definition for 'x' and 'y'. And they never get
used again in thsi function, so what they are goof for? 

>      count = 0;
>      do
>       { 
>         A = fuc (pF, pN, pD, pC, pB, pA);

'fuc()' is not a function anywhere in sight. Probably you meant
'funcB'? Or perhaps 'funcC'?

>         count = count + 1;
>        } while ((( z > = 0.0001) || ( z <= -0.0001)) && (count < limit));

You're never changing 'z' in this loop. So the loop will either
be run just once (if 'z' you started with is not in the interval
[-1e-4,1e-4]) or it will be run exacty 'limit' times.

>       if ( count == limit)
>       A = -1;
>       else
>       A = (pow (A, 12) - 1) * 100; 
>       A = (double) ((long long int) (( A + 0.005) * 100 )) / 100;

This looks a bit like you want to round 'A' to two digits
after the decimal point. In that case a more elegant so-
lution (without all these casts) might be to be

        A = 0.01 * floor( 100 * A + 0.5 );

Note that this (as your method) may not be what you want should
'A' ever be negative...

>       }

This closing curly brace would be the end of the function.
So something must be missing here/

>       A = A * 1000;
>       r = (long int) A;
>       return (r);
>   }
>    

> double funcB (int pF, int pN, int pD, double pC, double pB, double pA) 
> { 
>   double F1, F2; 
>   F1 = pow (ACY, -parmN); 
>   F2 = pow (ACY, parmF); 

Neither 'ACY' nor 'paramN' or 'paramH' are defined (and assigned a
value) anywhere I can see.

>   z = ((F2 * ACY - 1) ) / (1 - F1));

'z' is not defined. And there's one too many ')' here.

>   z = pB/ z;
>   z = z - pA - (pC/ pow (ACY, pD));
>   return (z);
> }


>   double funcC (int pF, int pN, int pD, double pC, double pB, double pA) 
>    { 
>       double a,b,c,d,e;
>       a = x - v; 
>       b = w - y;  
>       A = V + (fabs(w)/ ((fabs(b)) / (a)));
>       z = funcB (pF, pN, pD, PC, pB, pA); 

No definitions for 'x', 'v', 'w', 'y', 'A', 'V' 'w' or 'z'. Note
that C distinguishes between upper- and lower-case variable names,
so 'v' is a different variable than 'V'. Same for 'a' and 'A'.

>      if (z > 0) 
>      { 
>      v = A; 
>      w = z; 
>      } else if (z < 0) 
>      { 
>      x = A ;  
>      y = z; 
>      } 

What about the case that 'z' is exactly 0?

>      return (A); 
>      } 

> Not using a C++ compiler. Just using the C89 compiler. Of that I'm sure.
> Will try some C++ code and try to execute using the same compiler tomorrow,
> just to be double sure.

> -- I'd try to simply print out the value of the nacro DBL_MIN from 
> -- <limits.h> to check if this what's going on your machine. 

> I'd try the above also tomorrow.

> Also just to state it clear the source file has only the above code. And it
> is compiled.

Then the source code you have is definitely not what you show
above. There's no chance that what you posted here would ever
compile. Not with a C (nor with a C++) compiler, sorry.

> funcB and funcC are local here. (by local I mean, not used
> anywhere else outside this source file) But the funcA is called by the Cobol
> program who passes the input values onto the funcA. Those six Lp1, Lp2, etc.

> And somebody mentioned NaN on seeing the while condition for z. I'm not sure
> what NaN is.

'NaN' stands for "not a number". Floating points on modern
systems typically can be either valid numbers, NaN or Inf
(for infinity, and there's positive and negative infinity).
'NaN' can be used to mark a varuable not to hold a valid
numerical value. Several built-in C math functions may return
NaN if the input is NaN. And pow() may return NaN if the first
argument is negative and the second argument is a non-integer
- in that case 'errno' will be set to the value 'EDOM'. See
the documentation for your system on pow() to figure out what
exactly it will do on unsuitable input - it's not specified in
all detail in the C89 standard. All stated there is:

   The pow function computes x raised to the power y .  A domain error
   occurs if x is negative and y is not an integer.  A domain error
   occurs if the result cannot be represented when x is zero and y is
   less than or equal to zero.  A range error may occur.

The finer details are left to the implementors, i.e. who-ever
wrote the libm (C math library) for your system. It should be
documented somewhere.

> And this: 

> The general technique is to: 

> (a) include errno.h 
> (b) set errno = 0 before the function call in question (here, pow) 
> (c) test for errno == ERANGE after the call. 

Well, yes. First, there's a second value 'errno' can be set
to, 'EDOM' (domain error, i.e. the input was something pow()
can't be applied to). And then your program, as far as I un-
derstood, stops with some message about a "range error". That
sounds like your system is set up not to tolerate any such
errors and to ubstead kill the program instead. If that's
the case this will hapen before you have any chance to
check 'errno'. This could also be something that is set
up by the COBOL program from which you call the C functions
from. In that case the only practical solution might be to
check everything you pass to pow() to make sure there are
not any arguments that could trigger a program abort. Or
you may have to catch some "floating point exception" -
but how to do this is system-dependent.

> Below is the correct input that's usually passed into the program. (correct
> input)

> Lp1 = 1000000;
> Lp2 = 25000;
> Lp3 = 2;
> Lp4 = 60;
> Lp5 = 0;
> Lp6 = 0;

> For which the A value comes around 17.something which is right. 

> Below is the bad input for which the code does not stumble, but picks out
> the correct error catch - setting A to -1 ...

> Lp1 = 1759672;
> Lp2 = 23306;
> Lp3 = 2;
> Lp4 = 60;
> Lp5 = 0;
> Lp6 = 0;

> Another example.

> Lp1 = 1636100;
> Lp2 = 13844;
> Lp3 = 2;
> Lp4 = 60;
> Lp5 = 0;
> Lp6 = 0;

> Because for the above two bad inputs, the count reaches the limit (100) set
> in the program and sets the -1 value for A back to the calling COBOL
> program.

> Now the following is really bad input for which the code fails, unable to
> handle the range fault.

> Lp1 = 200000;
> Lp2 = 7345;
> Lp3 = 2;
> Lp4 = 12;
> Lp5 = 0;
> Lp6 = 0;

> The above input when reaching count 66, produces the following value for F1;

> F1 = 2.189569 e -77

> So at the 67th count, when it goes to funcC who calls funcB at line 5 of
> it's function - the first calculation of funcB is F1 where this time it
> hits a value far below the previous one. And it fails.

Give me some code I can compile and I'll try it with these values.
At the moment there's not enough information to even start guessing
what might happen.

> I've debugged the code, I've put in displays, introduced main () to print
> these outputs and so much more. I can find this really bad input even before
> passing onto funcC who passes it onto funcB - but I don't want to be the
> judge of that. I want the program to decide whether the range fault occurs
> and if so, then let the calling program know that the input is bad - by
> setting the value of A as -1, just like the other bad inputs do.

If you have already a working compiling C program for testing
then I would strongly recommend to post it exactly as it is
and not something that is only a rough approximation. Copy
and paste and don't re-type it! This will safe everyones
time;-)
                     Regards, Jens
-- 
  \   Jens Thoms Toerring  ___      jt@toerring.de
   \__________________________      http://toerring.de

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web