Home > Archive > Fortran > June 2007 > Exponentiation Operator
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Exponentiation Operator
|
|
|
| Exponentiation
First, let me admit that I am rather hesitant
to ask for help/opinion since things seem to behave
just fine in a 10-line program with no subroutines
nor common blocks or anything; but they do
not in my 1500-line program.
If it wasn't because the behaviour is so
consistent, I would think it is a memory
problem; but the results don't change if I
modify the program here and there to move
stuff around.
In Linux (x86_64) with g95, my problem is
that a formula like
(1.0 - 0.002*A/500.0)**5.25
returns 10.0 (regardless of the value of A)
when I compile my program with -r8.
Then:
- If I compile WITHOUT -r8, everything is fine.
- If I use INTEGER exponent, everything is fine.
- If I compile back with -r8, and locally/explicitely
declare a few REAL*4 variables and use them in the
formula above, so that no hard coded constants
appear in the formula, then everything is fine.
Does this sound familiar to anyone?
Any ideas would be greatly appreciated.
gsal
P.S. By the way, exp(k1*log(k2)) works just fine
| |
| John Harper 2007-06-24, 10:06 pm |
| In article <1182722726.438055.193060@c77g2000hse.googlegroups.com>,
gsal <salgerman@gmail.com> wrote:
>Exponentiation
>
>First, let me admit that I am rather hesitant
>to ask for help/opinion since things seem to behave
>just fine in a 10-line program with no subroutines
>nor common blocks or anything; but they do
>not in my 1500-line program.
>
>In Linux (x86_64) with g95, my problem is
>that a formula like
>
> (1.0 - 0.002*A/500.0)**5.25
>
>returns 10.0 (regardless of the value of A)
>when I compile my program with -r8.
>
>Then:
>
>- If I compile WITHOUT -r8, everything is fine.
>
>- If I use INTEGER exponent, everything is fine.
>
>- If I compile back with -r8, and locally/explicitely
>declare a few REAL*4 variables and use them in the
>formula above, so that no hard coded constants
>appear in the formula, then everything is fine.
Something you haven't shown us is probably causing that trouble.
To start with, you say "a formula like (1.0 - 0.002*A/500.0)**5.25"
not "the formula (1.0 - 0.002*A/500.0)**5.25" so we have no evidence
that what you told is the exact formula that gave 10.0 as a result.
Are you absolutely utterly certain that nothing else is wrong in
your 1500 lines, that A is what you think it is (real, scalar, ...),
that it had been given a value before being used, and that 10.0,
not 10.0002 for example, really is the value of what you said it
was rather than the value of something else?
I'd check all that with a pair of statements, with no other statements
between them, like these:
PRINT*,' A = ',A,' kind(A) = ', kind(A)
PRINT*,'(1.0 - 0.002*A/500.0)**5.25=', (1.0 - 0.002*A/500.0)**5.25
If the trouble persists, and you still can't trace it, try taking stuff
out of your 1500-liner until you get the shortest program that still
gives a bad reult. Few people here have the spare time to read other
people's 1500-line programs :-) And you can't expect precise information
from us unless you quote your your exact program, and exactly what you
asked the machine to do with it, and exactly what the output was.
-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
| |
|
|
John, thanks for your prompt reply and advice, it did took
me out of my stuborn focus on the one subroutine where the
problem seems to appear.
I went ahead and started to do what you say: take stuff out.
I wrote a subroutine:
subroutine check
PRINT*,' A = ',A,' kind(A) = ', kind(A)
PRINT*,'(1.0 - 0.002*A/500.0)**5.25=', (1.0 - 0.002*A/500.0)**5.25
stop
end
and then I wrote a line "call check" and started to move
that line from the beginning of my program and down the
code to see when the problem appears.
At first, 'call check' yields 1.0 for the formula above, as
it should be (A=0.0); then, later on in the code, it becomes
0.0
Something really weird is going on, depending on what I have
in my code, the problem appears at different points, but when
it does, it appears right after a WRITE statement, when I am
attempting to write some string variable. Observe that the problem
does not appear when I set the string variable, but when I attempt
to print its value or print just a string constant.
What's up with that? It seems that the problem is circumvented
if, instead of writing the entire string in one shot, I write it
one character at a time inside a loop...go figure.
I will keep investigating.
gsal
| |
| Herman D. Knoble 2007-06-25, 8:06 am |
| 2*D-3 * 2.D-3 = 4*D-6
is being multiplied by the value of A which likely was (for you) relatively
small (less than 1.D+6.
So it would seem that relatively small values of A will yield result
of about 1.0 to be further operated on (exponentiated in this case).
Skip Knoble
On Sun, 24 Jun 2007 15:05:26 -0700, gsal <salgerman@gmail.com> wrote:
-|Exponentiation
-|
-|First, let me admit that I am rather hesitant
-|to ask for help/opinion since things seem to behave
-|just fine in a 10-line program with no subroutines
-|nor common blocks or anything; but they do
-|not in my 1500-line program.
-|
-|If it wasn't because the behaviour is so
-|consistent, I would think it is a memory
-|problem; but the results don't change if I
-|modify the program here and there to move
-|stuff around.
-|
-|In Linux (x86_64) with g95, my problem is
-|that a formula like
-|
-| (1.0 - 0.002*A/500.0)**5.25
-|
-|returns 10.0 (regardless of the value of A)
-|when I compile my program with -r8.
-|
-|Then:
-|
-|- If I compile WITHOUT -r8, everything is fine.
-|
-|- If I use INTEGER exponent, everything is fine.
-|
-|- If I compile back with -r8, and locally/explicitely
-|declare a few REAL*4 variables and use them in the
-|formula above, so that no hard coded constants
-|appear in the formula, then everything is fine.
-|
-|Does this sound familiar to anyone?
-|
-|Any ideas would be greatly appreciated.
-|
-|gsal
-|
-|P.S. By the way, exp(k1*log(k2)) works just fine
| |
| tianyf@gmail.com 2007-06-25, 10:07 pm |
| On Jun 25, 12:31 pm, gsal <salger...@gmail.com> wrote:
> Something really weird is going on, depending on what I have
> in my code, the problem appears at different points, but when
Did you call other subroutines/functions before it?
If so, check the type and dimensions of their parameters. A mismatch
of type/size will cause unexpectable results.
Cheers,
Tian
| |
| Dick Hendrickson 2007-06-25, 10:07 pm |
| gsal wrote:
> John, thanks for your prompt reply and advice, it did took
> me out of my stuborn focus on the one subroutine where the
> problem seems to appear.
>
> I went ahead and started to do what you say: take stuff out.
>
> I wrote a subroutine:
>
> subroutine check
> PRINT*,' A = ',A,' kind(A) = ', kind(A)
> PRINT*,'(1.0 - 0.002*A/500.0)**5.25=', (1.0 - 0.002*A/500.0)**5.25
> stop
> end
>
> and then I wrote a line "call check" and started to move
> that line from the beginning of my program and down the
> code to see when the problem appears.
>
> At first, 'call check' yields 1.0 for the formula above, as
> it should be (A=0.0); then, later on in the code, it becomes
> 0.0
>
> Something really weird is going on, depending on what I have
> in my code, the problem appears at different points, but when
> it does, it appears right after a WRITE statement, when I am
> attempting to write some string variable. Observe that the problem
> does not appear when I set the string variable, but when I attempt
> to print its value or print just a string constant.
> What's up with that? It seems that the problem is circumvented
> if, instead of writing the entire string in one shot, I write it
> one character at a time inside a loop...go figure.
>
> I will keep investigating.
>
> gsal
>
>
On Intel-like machines, operands are often kept in extra length
registers. When they are stored into memory, the extra precision
is lost. I/O statements and subroutine calls usually force things to
be stored into memory. So, if you do something like
this = blah...
that = blahblah...
A = this - that
you can get surprisingly different answers for A if you insert a
write statement into the sequence.
Dick Hendrickson
| |
|
|
Found the problem.
Well, like I admitted in my original posting,
I did notice that a 5-line program works just
fine; hence, it had to be my 1500-line program
the one introducing the "bug".
I resourced to start with an empty file and
bringing more and more code until the "bug"
appeared; I even had to bring sources of
10-year old libraries I was linking against,
that were written for Sun's f77 (in SunOS).
At the end, it turned out that one of the
libraries I was linking had a "local" function
named POW. I say "local" because it is not
protected or encapsulated in anyway, but it is
intended for the library's own use.
As far as I can tell, POW is not a fortran
intrinsic function, nor g95 instrinsic; but it
seems that g95 uses, behind the scenes, a
function named POW to carry out the functionality
of the expnentiation operator, which was then
being overwritten by my library's own POW, which
of course, did something else.
If this is actually the case, is this my mistake?
or should a compiler be more protective of such
internal functions? I mean, I presume that I can
override a function named SIN with some other
functionality, but at least I know I am doing it,
since SIN is advertised as a fortran instrinsic
function.
Should I persue this? I don't mind at least
posting this in the g95 group since it seems
to be particular to that compiler.
gsal.
P.S. thanks to everybody for all the tips.
| |
|
| gsal wrote:
> Found the problem.
>
....
> At the end, it turned out that one of the
> libraries I was linking had a "local" function
> named POW. ...
> intended for the library's own use.
>
> As far as I can tell, POW is not a fortran
> intrinsic function, nor g95 instrinsic; but it
> seems that g95 uses, behind the scenes, a
> function named POW to carry out the functionality
> of the expnentiation operator, which was then
> being overwritten by my library's own POW, which
> of course, did something else.
>
> If this is actually the case, is this my mistake?
....
If this is the case (and symptoms sound plausible, certainly) you could
test it w/ a very simple few-line program that has little more than a
reference to the library function and the exponentiation operation.
It does seem as though the name "POW" would be more highly decorated to
prevent name clashes in an internal compiler use, but I suppose it's
possible but would seem that it would have bitten somebody else before now.
I'd suggest trying to make a test case and post it for others to evaluate.
--
| |
|
| O.k., I think I got it.
Using Linux (x86_64) and g95 version 0.91
Here is the minimal f77 program
program try
a = 0.0
print*,'(1.0 - 0.002*a/500.0)**5.25=', (1.0 - 0.002*a/
500.0)**5.25
end
real function pow(n)
integer n
pow = 99.99
return
end
If you compile this with
> g95 try.f
it should work fine.
If you compile this program with
> g95 -r8 -fno-underscoring try.f
then, it seems that the 'pow' function
gets called during exponentiation.
Will you please verify?
thanks.
gsal
| |
| Steven G. Kargl 2007-06-26, 10:06 pm |
| In article <f5r79f$aab$1@aioe.org>,
dpb <none@non.net> writes:
>
> If this is the case (and symptoms sound plausible, certainly) you could
> test it w/ a very simple few-line program that has little more than a
> reference to the library function and the exponentiation operation.
>
> It does seem as though the name "POW" would be more highly decorated to
> prevent name clashes in an internal compiler use, but I suppose it's
> possible but would seem that it would have bitten somebody else before now.
>
> I'd suggest trying to make a test case and post it for others to evaluate.
pow is a function that resides in libm. On any decent Unix-like
OS, do
%man pow
EXP(3) FreeBSD Library Functions Manual EXP(3)
NAME
exp, expf, exp2, exp2f, expm1, expm1f, log, logf, log10, log10f, log1p,
log1pf, pow, powf -- exponential, logarithm, power functions
Now, do g95 -v, which shows all the ugly library linking. You'll
see -lm in the mess. So, gsal's problem is
g95 -o a somefile.f90 -lib_with_bad_pow
becomes soemthing like
ld -o somefile.o -lib_with_bad_pow -L/usr/lib -lg95 -lm -lc
because -lib_with_bad_pow appears before -lm, gsal gets the wrong
pow function.
--
Steve
http://troutmask.apl.washington.edu/~kargl/
| |
| Richard Maine 2007-06-26, 10:06 pm |
| gsal <salgerman@gmail.com> wrote:
> As far as I can tell, POW is not a fortran
> intrinsic function, nor g95 instrinsic; but it
> seems that g95 uses, behind the scenes, a
> function named POW to carry out the functionality
> of the expnentiation operator, which was then
> being overwritten by my library's own POW, which
> of course, did something else.
>
> If this is actually the case, is this my mistake?
> or should a compiler be more protective of such
> internal functions? I mean, I presume that I can
> override a function named SIN with some other
> functionality, but at least I know I am doing it,
> since SIN is advertised as a fortran instrinsic
> function.
Yes, I'd call that a compiler bug. Actually, note that you can *BOTH*
override SIN and still have the original one. The limitation is only
against using the same name for 2 things in the same scope. You can,
however, use your SIN in one scope unit and the intrinsic one in
another. You can even use them both in the same scope, as long as you
play games so that they have different local names in that scope (there
are ways to do that). The compiler needs to accomodate such things. this
is almost invariably done by "decorating" user Fortran procedure names
behind your back so that they won't conflict with system names.
And nothing you do with SIN should affect any internal uses that the
compiler might put it to.
The compiler is supposed to "protect" its internals from such things.
You can and should use the EXTERNAL attribute to make sure that you get
your own procedures instead of compiler-specific intrinsics (or even
standard intrinsics that you didn't know about or were added in a leter
version of the standard). If you were getting the cmpiler's pow instead
of your own, then that would count as a problem with your code,which
would be fixed by specifying EXTERNAL. It doesn't sound like that is
your problem (though I didn't read carefully enough to rule it out for
sure).
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| glen herrmannsfeldt 2007-06-26, 10:07 pm |
| Richard Maine wrote:
> gsal <salgerman@gmail.com> wrote:
It is a C library function. Unlike Fortran, it is
called explicitly in C.
[color=darkred]
[color=darkred]
> Yes, I'd call that a compiler bug. Actually, note that you can *BOTH*
> override SIN and still have the original one. The limitation is only
> against using the same name for 2 things in the same scope. You can,
But the OP said:
g95 -r8 -fno-underscoring try.f
That is, he specifically overrides the protective underscore
that the compiler tried to use. In that case, I would say it
is the users responsibility to worry about such problems.
(snip)
With the ability to provide protection, and the ability to
override it when needed, such as to call C library routines,
at some point there is likely to be a conflict.
-- glen
| |
|
| glen herrmannsfeldt wrote:
....snip on how to avoid conflict w/ user-supplied of same name as
intrinsic...
> But the OP said:
>
> g95 -r8 -fno-underscoring try.f
>
> That is, he specifically overrides the protective underscore
> that the compiler tried to use. In that case, I would say it
> is the users responsibility to worry about such problems.
That is what I either didn't see or wasn't posted earlier -- I remember
the -r8 on the earlier example, I didn't the -fno-underscoring. As you
say, that is key...
--
| |
|
|
Well, you have a good point.
Then again:
- it seems that the compiler cannot tell its own C function
call apart from my Fortran function, even though, they have
different signatures
- it cannot tell between function and subroutine, either,
consider this:
program try
a = 3.0
print*,'a**5.25=', a**5.25
end
subroutine pow
end
> g95 -r8 -fno-underscoring try.f
> a.out
> a**5.25= 3.
gsal
| |
| Steven G. Kargl 2007-06-26, 10:07 pm |
| In article <1182883616.949673.171040@k79g2000hse.googlegroups.com>,
gsal <salgerman@gmail.com> writes:
>
> Well, you have a good point.
>
> Then again:
>
> - it seems that the compiler cannot tell its own C function
> call apart from my Fortran function, even though, they have
> different signatures
>
You're getting EXACTLY what you asked to compiler to do.
Don't use options that you don't understand.
--
Steve
http://troutmask.apl.washington.edu/~kargl/
| |
| Richard Maine 2007-06-26, 10:07 pm |
| glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
> Richard Maine wrote:
[color=darkred]
> But the OP said:
>
> g95 -r8 -fno-underscoring try.f
>
> That is, he specifically overrides the protective underscore
> that the compiler tried to use. In that case, I would say it
> is the users responsibility to worry about such problems.
Oh. I missed that. Yes, I 100% agree.
That option is a hack specifically to override the compiler's "good
sense" in the matter. It basically says to the compiler "trust me; I'm
intentionally wanting to use the same namespace (probably not the right
technical term) as the system functions; I know what that implies and I
want to do it." It is a "dangerous" option; I generally recommend
against it.
Unfortunately, I've sometimes seen the option recommended as a "quick
fix" for things like useing a C library function from Fortran. The
problem, of course, is that it changes more than just the one function
you are trying to use. It changes teh entire program. (You pretty much
have to do everything in the program the same way).
The f2003 C interop stuff provides a safer way to do what I've most
often seen that option used for.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| John Harper 2007-06-26, 10:07 pm |
| In article <1i0b7mw.f17fr36aas4eN%nospam@see.signature>,
Richard Maine <nospam@see.signature> wrote:
>
>You can and should use the EXTERNAL attribute to make sure that you get
>your own procedures instead of compiler-specific intrinsics (or even
>standard intrinsics that you didn't know about or were added in a leter
>version of the standard). If you were getting the cmpiler's pow instead
>of your own, then that would count as a problem with your code,which
>would be fixed by specifying EXTERNAL. It doesn't sound like that is
>your problem (though I didn't read carefully enough to rule it out for
>sure).
It wasn't. I tried adding EXTERNAL pow to the OP's program and it still
did what he didn't expect but did unwittingly ask for when specifying
the -fno-underscoring option. The trouble, as others have pointed out,
is that that option does more than one might at first imagine.
-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
| |
|
|
O.k., then, I think we got to the bottom of this one.
Yes, I was using it so that I did not have to append
an underscore to my own C functions.
No, I did not know the extent of -fno-underscoring.
No, I did not know that it was going to affect compiler's
own behind-the-scene calls.
No, I did not know that the compiler could (mis)take my
own SUBROUTINE/FUNCTION instead of a C function regardless
of signature.
....but now I know.
Thank you all for all your comments and feedback.
gsal
| |
|
|
| glen herrmannsfeldt 2007-06-30, 8:05 am |
| gsal wrote:
> O.k., then, I think we got to the bottom of this one.
> Yes, I was using it so that I did not have to append
> an underscore to my own C functions.
> No, I did not know the extent of -fno-underscoring.
> No, I did not know that it was going to affect compiler's
> own behind-the-scene calls.
I wouldn't say that it affects the compilers own calls,
but it affects all the other calls such that they don't look
different than the compilers own calls. Specifically, they
don't look different than C library calls. C doesn't
have generic functions (at least C89 doesn't).
> No, I did not know that the compiler could (mis)take my
> own SUBROUTINE/FUNCTION instead of a C function regardless
> of signature.
The possibility should have been documented with
-fno-underscoring. Still, it is an easy mistake to make.
-- glen
|
|
|
|
|