Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Logic of a Function 1

Status
Not open for further replies.

Panavia

Technical User
Nov 14, 2010
15
0
0
DE
Hi,

I have a small problem understanding the following peace of code. It should be very simple but for me, coming from a visual basic background, it doesn't make sense.

Code:
  FUNCTION IFRAC(R)
    IMPLICIT REAL*8(A-H, O-Z)
    IFRAC=R
    IF (R.GE.0) RETURN
    IF (R.EQ.IFRAC) RETURN
    IFRAC = IFRAC - 1
    RETURN
  END

The variable "R" is passed trough from a preceding peace of code.

So here are my questions:
Is the expression "IFRAC" considered a variable or something else since it hasn't been declared and for my understanding it is not included in the general declaration of "IMPLICIT REAL*8(A-H, O-Z)"...

Then:
Isn't the code processed from top to bottom?
If so, how much sense does it make to set "IFRAC" equal to "R" and then RETURN if "IFRAC" is equal to "R" (rows 3 vs. 5)?

Thanks for your help!
Tobias
 
Because of the declaration
Code:
IMPLICIT REAL*8(A-H, O-Z)
the function argument R is REAL*8, but the result of the function IFRAC is INTEGER because it begins with I.
Therefore for R = 3.14 the assignment IFRAC = R results in IFRAC = 3
To understand it, look at this example:
ifrac_test.f95
Code:
[COLOR=#a020f0]program[/color] ifrac_test
[COLOR=#2e8b57][b]  real[/b][/color][COLOR=#804040][b]*[/b][/color][COLOR=#ff00ff]8[/color] :: r
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]5[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]3.14[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]EXP[/color]([COLOR=#ff00ff]1.0[/color])
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)
[COLOR=#a020f0]contains[/color]
  [COLOR=#a020f0]FUNCTION[/color] IFRAC(R)
    [COLOR=#2e8b57][b]IMPLICIT REAL[/b][/color][COLOR=#804040][b]*[/b][/color][COLOR=#ff00ff]8[/color](A[COLOR=#804040][b]-[/b][/color]H, O[COLOR=#804040][b]-[/b][/color]Z)
    IFRAC[COLOR=#804040][b]=[/b][/color]R
    [COLOR=#804040][b]IF[/b][/color] (R[COLOR=#804040][b].GE.[/b][/color][COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]RETURN[/b][/color]
    [COLOR=#804040][b]IF[/b][/color] (R[COLOR=#804040][b].EQ.[/b][/color]IFRAC) [COLOR=#804040][b]RETURN[/b][/color]
    IFRAC [COLOR=#804040][b]=[/b][/color] IFRAC [COLOR=#804040][b]-[/b][/color] [COLOR=#ff00ff]1[/color]
    [COLOR=#804040][b]RETURN[/b][/color]
  [COLOR=#a020f0]END FUNCTION[/color]
[COLOR=#a020f0]end program[/color]
Results:
Code:
$ g95 ifrac_test.f95 -o ifrac_test

$ ifrac_test
 IFRAC( 5. ) =  5
 IFRAC( 3.140000104904175 ) =  3
 IFRAC( 2.7182817459106445 ) =  2
 
Thanks a lot!

So do I understand it correctly that the code I posted returns if:
- "R" is greater or equal to 0
- "R" is a whole number without decimals
and only subtracts 1 of the whole number in front of the decimals of "R" if those two cases don't apply?

Does the fact that the function name and the Integer "IFRAC" are written the same way has any effect. That's what I suspected...?

Tobias
 
I forgot to say, that it's better to use IMPLICIT NONE and declare the types of all variables explicitly. Then you avoid such misunderstandings.

The substraction
IFRAC = IFRAC - 1
applies only when R < 0.

I hope the following example helps you to understand what I wrote above:
ifrac_test2.f95
Code:
[COLOR=#a020f0]program[/color] ifrac_test
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
[COLOR=#2e8b57][b]  real[/b][/color][COLOR=#804040][b]*[/b][/color][COLOR=#ff00ff]8[/color] :: r
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]5[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]3.14[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]EXP[/color]([COLOR=#ff00ff]1.0[/color])
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#804040][b]-[/b][/color][COLOR=#ff00ff]5[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#804040][b]-[/b][/color][COLOR=#ff00ff]3.14[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)
  r [COLOR=#804040][b]=[/b][/color] [COLOR=#804040][b]-[/b][/color][COLOR=#008080]EXP[/color]([COLOR=#ff00ff]1.0[/color])
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'IFRAC('[/color],r,[COLOR=#ff00ff]') = '[/color], IFRAC(R)  
[COLOR=#a020f0]contains[/color]
  [COLOR=#2e8b57][b]INTEGER[/b][/color] [COLOR=#a020f0]FUNCTION[/color] IFRAC(R)
[COLOR=#2e8b57][b]    REAL[/b][/color][COLOR=#804040][b]*[/b][/color][COLOR=#ff00ff]8[/color] :: R
    IFRAC[COLOR=#804040][b]=[/b][/color]R
    [COLOR=#804040][b]IF[/b][/color] (R[COLOR=#804040][b].GE.[/b][/color][COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]RETURN[/b][/color]
    [COLOR=#804040][b]IF[/b][/color] (R[COLOR=#804040][b].EQ.[/b][/color]IFRAC) [COLOR=#804040][b]RETURN[/b][/color]
    IFRAC [COLOR=#804040][b]=[/b][/color] IFRAC [COLOR=#804040][b]-[/b][/color] [COLOR=#ff00ff]1[/color]
    [COLOR=#804040][b]RETURN[/b][/color]
  [COLOR=#a020f0]END FUNCTION[/color]
[COLOR=#a020f0]end program[/color]
Results:
Code:
$ g95 ifrac_test2.f95 -o ifrac_test2

$ ifrac_test2
 IFRAC( 5. ) =  5
 IFRAC( 3.140000104904175 ) =  3
 IFRAC( 2.7182817459106445 ) =  2
 IFRAC( -5. ) =  -5
 IFRAC( -3.140000104904175 ) =  -4
 IFRAC( -2.7182817459106445 ) =  -3
 
Awesome thanks!
That helps a lot.
Tobias
 
you can write the function at other way, so that it RETURNs only at the end - for example so:
Code:
  [COLOR=#2e8b57][b]INTEGER[/b][/color] [COLOR=#a020f0]FUNCTION[/color] IFRAC(R)
[COLOR=#2e8b57][b]    REAL[/b][/color][COLOR=#804040][b]*[/b][/color][COLOR=#ff00ff]8[/color] :: R
    IFRAC[COLOR=#804040][b]=[/b][/color]R
    [COLOR=#804040][b]IF[/b][/color] (R[COLOR=#804040][b].GE.[/b][/color][COLOR=#ff00ff]0[/color] [COLOR=#804040][b].OR.[/b][/color] R[COLOR=#804040][b].EQ.[/b][/color]IFRAC) [COLOR=#804040][b]THEN[/b][/color]
      [COLOR=#0000ff]! return IFRAC=R[/color]
      [COLOR=#804040][b]CONTINUE[/b][/color]
    [COLOR=#804040][b]ELSE[/b][/color]
      IFRAC [COLOR=#804040][b]=[/b][/color] IFRAC [COLOR=#804040][b]-[/b][/color] [COLOR=#ff00ff]1[/color]
    [COLOR=#804040][b]END IF[/b][/color]
  [COLOR=#a020f0]END FUNCTION[/color]
or so:
Code:
  [COLOR=#2e8b57][b]INTEGER[/b][/color] [COLOR=#a020f0]FUNCTION[/color] IFRAC(R)
[COLOR=#2e8b57][b]    REAL[/b][/color][COLOR=#804040][b]*[/b][/color][COLOR=#ff00ff]8[/color] :: R
    IFRAC[COLOR=#804040][b]=[/b][/color]R
    [COLOR=#804040][b]IF[/b][/color] ([COLOR=#804040][b].NOT.[/b][/color](R[COLOR=#804040][b].GE.[/b][/color][COLOR=#ff00ff]0[/color] [COLOR=#804040][b].OR.[/b][/color] R[COLOR=#804040][b].EQ.[/b][/color]IFRAC)) [COLOR=#804040][b]THEN[/b][/color]
      IFRAC [COLOR=#804040][b]=[/b][/color] IFRAC [COLOR=#804040][b]-[/b][/color] [COLOR=#ff00ff]1[/color]
    [COLOR=#804040][b]END IF[/b][/color]
  [COLOR=#a020f0]END FUNCTION[/color]
 
OK, that helps to sweeten the code.
I thinhk I'll use the second expression.
Thanks!
 
Would your code translated into Visual Basic look something like this?

Code:
Dim IFRAC As Integer
Dim R as Double = 3.14
   If Not R >= 0 Or R = Math.Floor(R) Then IFRAC = Math.Floor(R) - 1
 
I don't have VB and never used it, but I doubt if in VB is
Code:
Not R >= 0 Or R = Math.Floor(R)
the same as
Code:
Not (R >= 0 Or R = Math.Floor(R))

But I'm using VBscript and the Fortran example I posted above rewritten in VBscript would be something like this:
ifrac_test.vbs
Code:
r [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]5[/color]
wscript[COLOR=#804040][b].[/b][/color]echo [COLOR=#ff00ff]"IFRAC("[/color] [COLOR=#804040][b]&[/b][/color] r [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]") = "[/color] [COLOR=#804040][b]&[/b][/color] IFRAC[COLOR=#804040][b]([/b][/color]r[COLOR=#804040][b])[/b][/color]
r [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]3.14[/color]
wscript[COLOR=#804040][b].[/b][/color]echo [COLOR=#ff00ff]"IFRAC("[/color] [COLOR=#804040][b]&[/b][/color] r [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]") = "[/color] [COLOR=#804040][b]&[/b][/color] IFRAC[COLOR=#804040][b]([/b][/color]r[COLOR=#804040][b])[/b][/color]
r [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]exp[/color][COLOR=#804040][b]([/b][/color][COLOR=#ff00ff]1.0[/color][COLOR=#804040][b])[/b][/color]
wscript[COLOR=#804040][b].[/b][/color]echo [COLOR=#ff00ff]"IFRAC("[/color] [COLOR=#804040][b]&[/b][/color] r [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]") = "[/color] [COLOR=#804040][b]&[/b][/color] IFRAC[COLOR=#804040][b]([/b][/color]r[COLOR=#804040][b])[/b][/color]
r [COLOR=#804040][b]=[/b][/color] [COLOR=#804040][b]-[/b][/color][COLOR=#ff00ff]5[/color]
wscript[COLOR=#804040][b].[/b][/color]echo [COLOR=#ff00ff]"IFRAC("[/color] [COLOR=#804040][b]&[/b][/color] r [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]") = "[/color] [COLOR=#804040][b]&[/b][/color] IFRAC[COLOR=#804040][b]([/b][/color]r[COLOR=#804040][b])[/b][/color]
r [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]-3.14[/color]
wscript[COLOR=#804040][b].[/b][/color]echo [COLOR=#ff00ff]"IFRAC("[/color] [COLOR=#804040][b]&[/b][/color] r [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]") = "[/color] [COLOR=#804040][b]&[/b][/color] IFRAC[COLOR=#804040][b]([/b][/color]r[COLOR=#804040][b])[/b][/color]
r [COLOR=#804040][b]=[/b][/color] [COLOR=#804040][b]-[/b][/color][COLOR=#008080]exp[/color][COLOR=#804040][b]([/b][/color][COLOR=#ff00ff]1.0[/color][COLOR=#804040][b])[/b][/color]
wscript[COLOR=#804040][b].[/b][/color]echo [COLOR=#ff00ff]"IFRAC("[/color] [COLOR=#804040][b]&[/b][/color] r [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]") = "[/color] [COLOR=#804040][b]&[/b][/color] IFRAC[COLOR=#804040][b]([/b][/color]r[COLOR=#804040][b])[/b][/color]

[COLOR=#0000ff]'--------------------------------------------[/color]
[COLOR=#804040][b]function[/b][/color] IFRAC[COLOR=#804040][b]([/b][/color]R[COLOR=#804040][b])[/b][/color]
  IFRAC [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]fix[/color][COLOR=#804040][b]([/b][/color]R[COLOR=#804040][b])[/b][/color]
  [COLOR=#804040][b]if[/b][/color] [COLOR=#804040][b]not([/b][/color]R [COLOR=#804040][b]>=[/b][/color] [COLOR=#ff00ff]0[/color] [COLOR=#804040][b]or[/b][/color] R [COLOR=#804040][b]=[/b][/color] IFRAC[COLOR=#804040][b])[/b][/color] [COLOR=#804040][b]then[/b][/color]
      IFRAC [COLOR=#804040][b]=[/b][/color] IFRAC [COLOR=#804040][b]-[/b][/color] [COLOR=#ff00ff]1[/color]
  [COLOR=#804040][b]end[/b][/color] [COLOR=#804040][b]if[/b][/color] 
[COLOR=#804040][b]end[/b][/color] [COLOR=#804040][b]function[/b][/color]
Results:
Code:
c:\msys\1.0\home\Roman\fortran>cscript /NoLogo ifrac_test.vbs
IFRAC(5) = 5
IFRAC(3,14) = 3
IFRAC(2,71828182845905) = 2
IFRAC(-5) = -5
IFRAC(-3,14) = -4
IFRAC(-2,71828182845905) = -3
 
It seems that it's Visual Basic Int(r) function - that's all.
 
yes in VBscript INT() function does the same:
Code:
int(5) = 5
int(3,14) = 3
int(2,71828182845905) = 2
int(-5) = -5
int(-3,14) = -4
int(-2,71828182845905) = -3
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top