|
|
 |
 |
 |
 |
Fortran Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
Program to convert binary <-> gray
Hey group, I just wrote a program that converts between binary and Gray vectors, and vice versa. I thought I'd make it openly available. Any comments/ suggestions welcome. Please feel free to criticise; your criticism = my lesson :-) skate xx ---------------------------------------------------------------- Program graytest Implicit None Integer:: i,length Integer, allocatable:: binary(:), gray(:) length = 4 Allocate (binary(length)) Allocate (gray(length)) gray(1) = 0 gray(2) = 0 gray(3) = 0 gray(4) = 1 Call gray_to_binary(length, binary,gray) Write (*,'(a10,100i3)') 'Binary =',binary(1:length) Write (*,'(a10,100i3)') 'Gray =',gray(1:length) End program graytest Subroutine binary_to_gray(length, binary, gray) Integer:: length, binary(length), gray(length) gray(length) = binary(length) do i = 1, length-1 gray(i) = xor(binary(i), binary(i+1)) enddo End subroutine binary_to_gray Subroutine gray_to_binary(length, binary, gray) Integer:: length, binary(length), gray(length), temp_bit binary(length) = gray(length) i = length - 1 do while (i >= 1) temp_bit = binary(i+1) temp_bit = xor(temp_bit, gray(i)) binary(i) = temp_bit i = i - 1 enddo End subroutine gray_to_binary
"sk8terg1rl" <sk8terg1rl_2 @yahoo.co.uk> wrote in message news:1178397974.386137.185420@n76g2000hsh.googlegroups.com... > Hey group, > I just wrote a program that converts between binary and Gray vectors, > and vice versa. I thought I'd make it openly available. Any comments/ > suggestions welcome. Please feel free to criticise; your criticism = > my lesson :-)
Well, nobody else replied, so here's your nice program with a few changes: subprograms in a module to get explicit (and checkable) interfaces; argument intent; remove while; and assumed-shape arrays. HTH Mike Metcalf module convert contains Subroutine binary_to_gray(binary, gray) Integer, intent(in):: binary(:) Integer, intent(out):: gray(:) Integer :: length length = size(binary) gray(length) = binary(length) do i = 1, length-1 gray(i) = xor(binary(i), binary(i+1)) enddo End subroutine binary_to_gray Subroutine gray_to_binary(binary, gray) Integer, intent(out):: binary(:) Integer, intent(in):: gray(:) Integer :: length, temp_bit length = size(gray) binary(length) = gray(length) i = length - 1 do temp_bit = binary(i+1) temp_bit = xor(temp_bit, gray(i)) binary(i) = temp_bit i = i - 1 if( i < 1) exit enddo End subroutine gray_to_binary end module convert Program graytest Use convert Implicit None Integer:: length Integer, allocatable:: binary(:), gray(:) length = 4 Allocate (binary(length)) Allocate (gray(length)) gray(1:3) = 0 gray(4) = 1 Call gray_to_binary(binary,gray) Write (*,'(a10,100i3)') 'Binary =',binary(1:length) Write (*,'(a10,100i3)') 'Gray =',gray(1:length) End program graytest
On May 7, 7:54 am, "Michael Metcalf" <michaelmetc@compuserve.com> wrote:
> "sk8terg1rl" <sk8terg1rl_2 @yahoo.co.uk> wrote in message > news:1178397974.386137.185420@n76g2000hsh.googlegroups.com...> Hey group, > > I just wrote a program that converts between binary and Gray vectors, > > and vice versa. I thought I'd make it openly available. Any comments/ > > suggestions welcome. Please feel free to criticise; your criticism = > > my lesson :-) > Well, nobody else replied, so here's your nice program with a few changes: > subprograms in a module to get explicit (and checkable) interfaces; argument > intent; remove while; and assumed-shape arrays. > HTH > Mike Metcalf > module convert
I suggest inserting implicit none private public :: binary_to_gray,gray_to_binary The arguments for implicit none are well known. One advantage of (private followed by public ::) is that one can look at the beginning of the module and see what can be USEd by other entities. > contains > Subroutine binary_to_gray(binary, gray) > Integer, intent(in):: binary(:) > Integer, intent(out):: gray(:)
I think this code assumes that size(binary) == size(gray), but it never checks for that. That is a mistake in production code. I would add comments and a test: Integer, intent(in):: binary(:) ! (length) Integer, intent(out):: gray(:) ! (length) Integer :: length length = size(binary) if (size(gray) /= length) then write (*,*) "in convert::binary_to_gray, size(binary), size(length) =",length,size(gray)," must be equal, STOPPING" stop end if
> Integer :: length > length = size(binary) > Integer :: length > length = size(binary) > gray(length) = binary(length) > do i = 1, length-1 > gray(i) = xor(binary(i), binary(i+1)) > enddo > End subroutine binary_to_gray > Subroutine gray_to_binary(binary, gray) > Integer, intent(out):: binary(:) > Integer, intent(in):: gray(:) > Integer :: length, temp_bit > length = size(gray) > binary(length) = gray(length) > i = length - 1 > do > temp_bit = binary(i+1) > temp_bit = xor(temp_bit, gray(i)) > binary(i) = temp_bit > i = i - 1 > if( i < 1) exit > enddo > End subroutine gray_to_binary > end module convert > Program graytest > Use convert > Implicit None > Integer:: length > Integer, allocatable:: binary(:), gray(:) > length = 4 > Allocate (binary(length)) > Allocate (gray(length)) > gray(1:3) = 0 > gray(4) = 1 > Call gray_to_binary(binary,gray) > Write (*,'(a10,100i3)') 'Binary =',binary(1:length) > Write (*,'(a10,100i3)') 'Gray =',gray(1:length) > End program graytest
"Beliavsky" <beliav @aol.com> wrote in message news:1178540949.730951.33200@h2g2000hsg.googlegroups.com...
> I suggest inserting > implicit none > private > public :: binary_to_gray,gray_to_binary > The arguments for implicit none are well known. One advantage of > (private followed by public ::) is that one can look at the beginning > of the module and see what can be USEd by other entities. >> contains >> Subroutine binary_to_gray(binary, gray) >> Integer, intent(in):: binary(:) >> Integer, intent(out):: gray(:) > I think this code assumes that size(binary) == size(gray), but it > never checks for that. That is a mistake in production code. I would > add comments and a test:
Agree to all that. Regards, Mike Metcalf
The variable, i , needs declared in both routines also. Skip On 7 May 2007 05:29:09 -0700, Beliavsky <beliav@aol.com> wrote: -|I suggest inserting -| -|implicit none -|private -|public :: binary_to_gray,gray_to_binary
"Herman D. Knoble" <SkipKnobleL@SPAMpsu.DOT.edu> wrote in message news:f8q043h5mbdfvkrg7faaq8th34oosdrpaq@4ax.com... > The variable, i , needs declared in both routines also.
Also, upon reflection, the while loop can actually be replaced by: do i = length - 1, 1, -1 temp_bit = binary(i+1) temp_bit = xor(temp_bit, gray(i)) binary(i) = temp_bit enddo as a reverse loop is what is clearly intended. Regards, Mike Metcalf
Hey all, On May 7, 12:54 pm, "Michael Metcalf" <michaelmetc@compuserve.com> wrote: > Well, nobody else replied, so here's your nice program with a few changes: > subprograms in a module to get explicit (and checkable) interfaces; argument > intent; remove while; and assumed-shape arrays.
Thanks for the replies :-) What exactly are the benefits of the above? I can sort of see why removing a "do while" might avoid an infinite loop, but I can't see why the other changes are a good idea. Also, why didn't you pass on the array dimensions as a variable into the subroutine? Or is doing so redundant as the binary & gray vectors already have a declared size? skate xx
> HTH > Mike Metcalf > module convert > contains > Subroutine binary_to_gray(binary, gray) > Integer, intent(in):: binary(:) > Integer, intent(out):: gray(:) > Integer :: length > length = size(binary) > gray(length) = binary(length) > do i = 1, length-1 > gray(i) = xor(binary(i), binary(i+1)) > enddo > End subroutine binary_to_gray > Subroutine gray_to_binary(binary, gray) > Integer, intent(out):: binary(:) > Integer, intent(in):: gray(:) > Integer :: length, temp_bit > length = size(gray) > binary(length) = gray(length) > i = length - 1 > do > temp_bit = binary(i+1) > temp_bit = xor(temp_bit, gray(i)) > binary(i) = temp_bit > i = i - 1 > if( i < 1) exit > enddo > End subroutine gray_to_binary > end module convert > Program graytest > Use convert > Implicit None > Integer:: length > Integer, allocatable:: binary(:), gray(:) > length = 4 > Allocate (binary(length)) > Allocate (gray(length)) > gray(1:3) = 0 > gray(4) = 1 > Call gray_to_binary(binary,gray) > Write (*,'(a10,100i3)') 'Binary =',binary(1:length) > Write (*,'(a10,100i3)') 'Gray =',gray(1:length) > End program graytest
Thanks, Mike. Also at the end of the sample main program, one might add: Deallocate(gray,binary) Skip On Tue, 08 May 2007 12:51:35 GMT, "Michael Metcalf" <michaelmetc @compuserve.com> wrote: -| -|"Herman D. Knoble" <SkipKnobleL@SPAMpsu.DOT.edu> wrote in message -|news:f8q043h5mbdfvkrg7faaq8th34oosdrpaq@4ax.com... -|> The variable, i , needs declared in both routines also. -|> -|Also, upon reflection, the while loop can actually be replaced by: -| -|do i = length - 1, 1, -1 -| temp_bit = binary(i+1) -| temp_bit = xor(temp_bit, gray(i)) -| binary(i) = temp_bit -|enddo -| -|as a reverse loop is what is clearly intended. -| -|Regards, -| -|Mike Metcalf -|
"sk8terg1rl" <sk8terg1rl_2 @yahoo.co.uk> wrote in message news:1178629077.398247.40540@y80g2000hsf.googlegroups.com... >> Well, nobody else replied, so here's your nice program with a few >> changes: >> subprograms in a module to get explicit (and checkable) interfaces; >> argument >> intent; remove while; and assumed-shape arrays. > Thanks for the replies :-) > What exactly are the benefits of the above? I can sort of see why > removing a "do while" might avoid an infinite loop, but I can't see > why the other changes are a good idea.
Well, this is just a small program, but in the real world one tries to program in such a way as to avoid as many sources of error as possible. One of the main sources in traditional Fortran is getting the interface between two procedures wrong. Putting procedures into a module makes interface checking at compile time possible. Giving arguments intent ensures they are actually used in the way intended (think about modifying a 100,000 line program in five years' time). Assumed-shape arrays avoid you having to pass explicit length information (the compiler will always get this right; the programmer will sometimes get it wrong). The other suggestions, about private, implicit none, all go in the same direction of 'defensive programming'. HTH, Mike Metcalf
On May 8, 8:57 am, sk8terg1rl <sk8terg1rl_2@yahoo.co.uk> wrote: > Hey all, > On May 7, 12:54 pm, "Michael Metcalf" <michaelmetc@compuserve.com> > wrote: > > Well, nobody else replied, so here's your nice program with a few changes: > > subprograms in a module to get explicit (and checkable) interfaces; argument > > intent; remove while; and assumed-shape arrays. > Thanks for the replies :-) > What exactly are the benefits of the above? I can sort of see why > removing a "do while" might avoid an infinite loop, but I can't see > why the other changes are a good idea.
I'll let others answer in detail, but let me say that some of the features of Fortran 90 *do* increase the amount of code that needs to be written to do a particular calculation. Those features can justify themselves in larger programs because more errors are caught at compile time and run time and because code can be easier to understand.
>> What exactly are the benefits of the above? I can sort of see why >> removing a "do while" might avoid an infinite loop, but I can't see >> why the other changes are a good idea. >Well, this is just a small program, but in the real world one tries to >program in such a way as to avoid as many sources of error as possible.
A related issue is in making the design intent clear. What you are trying to do should be very clear in your own mind as you write the code. But that internal clarity can deceive one into thinking that the source reads for others. External clarity is not the same as internal clarity. And even external clarity does not mean that your design intent is clear from just the source. Well written comments are one way of expressing intent, but code structure, variable naming and the choices, such as which looping constructs used, also express (or hide) design intent. So, Mike Metcalf's comments about providing the compiler with enough info to allow it to help you are spot on. He also mentioned about issues of extending the code some years out -- which are related to how well can one understand the code, whether it be another person, or yourself some time later. Understanding the code is aided by how well the code expresses the design intent. I can tell you from personal experience, you will bless (or curse) your earlier self repeatedly depending on how clear your expression not just of the coding details, but of your guiding and organizing principles (including design intent), when you revisit your code in the future. And unless you decide to leave coding forever, revisit it you will. Thank you for sharing your code for binary to gray and back again. I hope we all have given you some useful help in return. Sincerely Kevin
Kevin G. Rhoads <kgrho@alum.mit.edu> wrote: > A related issue is in making the design intent clear. What you are trying > to do should be very clear in your own mind as you write the code. But > that internal clarity can deceive one into thinking that the source reads > for others. External clarity is not the same as internal clarity. And > even external clarity does not mean that your design intent is clear from > just the source. Well written comments are one way of expressing intent, > but code structure, variable naming and the choices, such as which looping > constructs used, also express (or hide) design intent.
Clear expression of the design can also help your internal understanding - quite a lot actually. Many are the times when someone has asked me for debugging help, only to solve the problem themselves in the process of explaining it to me. This is a well-known phenomenon - that clearly expaining the problem to someone else can help you understand it better. This is much like learning something better by teaching it to someone else. Explicitly documenting things like argument intent and variable type provides a prompt to think about those important matters. Sometimes the prompt helps. -- Richard Maine | Good judgement comes from experience; email: last name at domain . net | experience comes from bad judgement. domain: summertriangle | -- Mark Twain
On May 5, 4:46 pm, sk8terg1rl <sk8terg1rl_2@yahoo.co.uk> wrote:
> Hey group, > I just wrote a program that converts between binary and Gray vectors, > and vice versa. I thought I'd make it openly available. Any comments/ > suggestions welcome. Please feel free to criticise; your criticism = > my lesson :-) > skate xx > ---------------------------------------------------------------- > Program graytest > Implicit None > Integer:: i,length > Integer, allocatable:: binary(:), gray(:) > length = 4 > Allocate (binary(length)) > Allocate (gray(length)) > gray(1) = 0 > gray(2) = 0 > gray(3) = 0 > gray(4) = 1 > Call gray_to_binary(length, binary,gray) > Write (*,'(a10,100i3)') 'Binary =',binary(1:length) > Write (*,'(a10,100i3)') 'Gray =',gray(1:length) > End program graytest > Subroutine binary_to_gray(length, binary, gray) > Integer:: length, binary(length), gray(length) > gray(length) = binary(length) > do i = 1, length-1 > gray(i) = xor(binary(i), binary(i+1)) > enddo > End subroutine binary_to_gray > Subroutine gray_to_binary(length, binary, gray) > Integer:: length, binary(length), gray(length), temp_bit > binary(length) = gray(length) > i = length - 1 > do while (i >= 1) > temp_bit = binary(i+1) > temp_bit = xor(temp_bit, gray(i)) > binary(i) = temp_bit > i = i - 1 > enddo > End subroutine gray_to_binary
I would suggest using IEOR instead of XOR (conforming to standard) // nobat
On May 8, 2:02 pm, nobat <sk.no@gmail.com> wrote: <snip> > I would suggest using IEOR instead of XOR (conforming to standard)
Good point. The OP should decide what standard she is complying with (I suggest either f95 or f2003) and use the appropriate compiler options. For g95 and gfortran, the option std=f95 enforces the Fortran 95 standard.
On 2007-05-08, Kevin G. Rhoads <kgrho@alum.mit.edu> wrote: > Well written comments are one way of expressing intent, > but code structure, variable naming and the choices, such as which looping > constructs used, also express (or hide) design intent.
Fortran needs INTENT(CLEAR), or so it seems. SCNR.
Thomas Koenig wrote: > On 2007-05-08, Kevin G. Rhoads <kgrho @alum.mit.edu> wrote: >> Well written comments are one way of expressing intent, >> but code structure, variable naming and the choices, such as which looping >> constructs used, also express (or hide) design intent. > Fortran needs INTENT(CLEAR), or so it seems. > SCNR.
No, that would invalidate far too many existing programs! Dick Hendrickson
>> Fortran needs INTENT(CLEAR), or so it seems. >No, that would invalidate far too many existing programs!
Besides which, if they added that to Fortran, people might start asking for it in C and C++ and then there would be REAL trouble.
Kevin G. Rhoads <kgrho@alum.mit.edu> wrote: > >> Fortran needs INTENT(CLEAR), or so it seems. > >No, that would invalidate far too many existing programs! > Besides which, if they added that to Fortran, people might > start asking for it in C and C++ and then there would be > REAL trouble.
Nah. That would be float trouble... or perhaps double trouble. -- Richard Maine | Good judgement comes from experience; email: last name at domain . net | experience comes from bad judgement. domain: summertriangle | -- Mark Twain
|
 |
 |
 |
 |
|