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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

converting if to math 2

Status
Not open for further replies.

j0zn

Programmer
Jul 19, 2013
36
BR
Hi guys! How to convert a expression with IF to only math?
I mean, how to transform the "if" in this following expression in a mathematical expression?
Thank you in advanced!

PROGRAM if_in_math
IMPLICIT none
INTEGER :: num

PRINT *, "Type a number"
READ *, num
IF(num.GE.0)THEN
PRINT *, num
END IF
END PROGRAM
 
j0zn said:
how to transform the "if" ... in a mathematical expression?
If you mean with "mathematical expression" rather a logical expresiion then there are sme languages, which support this style. They need to support short-circuit evaluation and need to return in boolean context not only True or False - but the real value of an expression.
I think that this functional style is not supported by Fortran, because it can retrun in boolean concept only True or False.

But, for example in Perl you can do this
Code:
[COLOR=#008080]$num[/color] = [COLOR=#ff00ff]5[/color];

[COLOR=#804040][b]if[/b][/color] ([COLOR=#008080]$num[/color] >= [COLOR=#ff00ff]0[/color]) {
  [COLOR=#804040][b]printf[/b][/color]([COLOR=#ff00ff]"[/color][COLOR=#ff00ff]%d >= 0[/color][COLOR=#6a5acd]\n[/color][COLOR=#ff00ff]"[/color], [COLOR=#008080]$num[/color]);
} 

[COLOR=#0000ff]# replacing above IF with logical expression [/color]
[COLOR=#008080]$v[/color] = (([COLOR=#008080]$num[/color] >= [COLOR=#ff00ff]0[/color]) && [COLOR=#008080]$num[/color]) || [COLOR=#ff00ff]""[/color];
[COLOR=#804040][b]printf[/b][/color]([COLOR=#ff00ff]"[/color][COLOR=#ff00ff]%s[/color][COLOR=#ff00ff]"[/color], [COLOR=#008080]$v[/color]);
which returns
Code:
5 >= 0
5

The same output could be done in Python
Code:
num = [COLOR=#ff00ff]5[/color]

[COLOR=#804040][b]if[/b][/color] (num >= [COLOR=#ff00ff]0[/color]):
  [COLOR=#008080]print[/color] [COLOR=#ff00ff]"%d >= 0"[/color] % num

[COLOR=#0000ff]# replacing above IF with logical expression[/color]
v = ((num >= [COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]and[/b][/color] num) [COLOR=#804040][b]or[/b][/color] [COLOR=#ff00ff]""[/color]
[COLOR=#008080]print[/color] [COLOR=#ff00ff]"%s"[/color] % v
 
You have to play with the function called isign. Something like this
Code:
subroutine disp(n)
   integer, intent(in):: n
   ! 3x3 = 9
   character(len=9)::output
   integer:: ibeg
   ! The inefficient bit
   write(output, '(3X,I3,I3)') n, n
   ! Workout which one to use
   ibeg = (isign(1, n) + 1) * 3 + 1
   write(*, *) output(ibeg:ibeg + 2)
end subroutine disp

program main
   call disp(-10)
   call disp(0)
   call disp(12)
end program
 
Yeah, I was thinking along the lines of sign, too.
Code:
program noif
    implicit none
    integer num
    character number(-1:1)*10 /3*'          '/  
 
    write(*,*) 'Type a number: '
    read(*,*) num
    write(number(1),'(i10)') num
    write(*,*) number( (num+sign(1,num))/(abs(num)+1) )
end program noif
 
I would like some code like this following. Avoiding function. I would like to know what is the step to evolute doing it
Link
 
Which function do you want to avoid. Why do you want to avoid it?
 
I would like to avoid use "if". Some time my program used to contain a lot of "ifs
 
Sometimes, IFs may be replaced efficiently by SELECT CASE constructs.

Another way is to use WHERE constructs which replaces in the same time DO loops and IF statements.

But for your example, the IF instruction is obviously the easiest way ! All the funny attempts to avoid it, as demonstrated by mikrom and xwb, have drawbacks like for instance an empty WRITE statement when num is <= 0 !

François Jacq
 
j0zn said:
How to convert a expression with IF to only math?
...
I would like to avoid use "if".
Some time my program used to contain a lot of "ifs"

If in your opinion a program contains too many IFs, it is very naive or stupid to try to replace these IFs even with mathematical or logical constructs.
Even though you should be able to do this, it would be very likely that in the end your program will be much more incomprehensible than before.

So if you want to avoid too many IFs then change your programming style.
 
mikrom, sometime it is really necessary. I am trying change and improve my programming style, even I'm beginner.
I am trying to do some analysis about some struture as a way to improve my programming style.
For example: I was thinking about how to chance it mathematics.

IF(lim_1>lim_2)THEN
interval = lim_1 - lim_2 + 1
lim_in = lim_2
ELSE
lim_in = lim_1
interval = lim_2 - lim_1 + 1
END IF
 
This time, it's easy :

Code:
interval = ABS(lim_1 - lim_2) + 1
lim_in = MAX(lim_2,linm_2)

François Jacq
 
Yes in this simple case, you only compute a length and beginning point of an interval which could be easily expressed using mathematical functions ABS() and MIN().
Although in my opinion the original code with IF is better understandable then the mathematical expressions with ABS and MIN. But it's philosophical question what of the both is better - my opinion is that explicit is better than implicit :)

With changing programming style I thought about dividing your long programming task into short subtasks. Then for every subtask you can write a subroutine or a function. Keep your subroutines and functions slim and you shall not have to bother with too much code on one place and optionally with too many nested IFs.

For example your code given above could be placed into a short subroutines, which takes on input lim_1 and lim_2 and returns interval and lim_in :
Code:
[COLOR=#a020f0]subroutine[/color] get_interval(lim_1, lim_2, interval, lim_in)
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#2e8b57][b]integer[/b][/color], [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]in[/b][/color]) :: lim_1, lim_2
  [COLOR=#2e8b57][b]integer[/b][/color], [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]out[/b][/color]) :: interval, lim_in

  [COLOR=#804040][b]if[/b][/color] (lim_1 [COLOR=#804040][b]>[/b][/color] lim_2) [COLOR=#804040][b]then[/b][/color]
    interval [COLOR=#804040][b]=[/b][/color] lim_1 [COLOR=#804040][b]-[/b][/color] lim_2 [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
    lim_in [COLOR=#804040][b]=[/b][/color] lim_2
  [COLOR=#804040][b]else[/b][/color]
    lim_in [COLOR=#804040][b]=[/b][/color] lim_1
    interval [COLOR=#804040][b]=[/b][/color] lim_2 [COLOR=#804040][b]-[/b][/color] lim_1 [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
  [COLOR=#804040][b]end if[/b][/color] 
[COLOR=#a020f0]end subroutine[/color] get_interval

The IF is now hidden in the subroutine. In the main program you only have to CALL the subroutine, so the code containing in the subroutine will not be irritating for you.
 
FJacq your idea to this was very good! Thank you!!

mikrom I going to try from today use subroutines. It become the program pretty organized. Thank you again for your tips!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top