Talk:Find the missing permutation: Difference between revisions

→‎Fortran example incorrect?: no, some gfortran versions have bug
(→‎Fortran example incorrect?: no, some gfortran versions have bug)
Line 116:
For now, I will leave the "incorrect" label, until we find a definite answer.
: I investigated this issue a bit further. The posted program is a correct fortran program (90 and later) and should give the correct result (see e.g. [http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/b327e38e69e4e622/2ea18cbd2a5af40f?lnk=raot this thread]). The version of gfortran tried by me (4.3.3 20080904 (prerelease)) gives a wrong result. More recent versions give the correct result. I am removing the "incorrect label". --[[User:Dsnouck|Dsnouck]] 07:56, 27 May 2010 (UTC)
 
 
:: The bug is more subtle than it seemed; the problem is bound to how gfortran handles parameters, in fact removing the parameter attribute it works the same in gfortran. I suppose there's also some relationship with how "strings" are handled. Using 1:1 and i:i "indipendently" does not change the result, as we expect, but when combined with == and slicing of a var with parameter attribute (immutable), the problem arises (and also it seems the error propagate, see the following long test code)
 
<lang fortran>program test
 
implicit none
character (2), dimension (2), parameter :: list = (/'ab', 'ba'/)
character (2), dimension (2) :: la = (/ 'a', 'b' /)
character, dimension(2) :: p
character :: t, t1
character(2) :: tt
integer :: i
 
i = 1
write (*, *) 'list(:)(1:1) = ', list (:) (1:1) ! a, b
write (*, *) ' size of prev = ', size(list (:) (1:1)) ! check that it is a, b
write(*, *) 'shape of prev : ', shape(list (:) (1:1))
 
write (*, *) '1:1 = ', list (1) (1:1) ! a
write (*, *) 'i:i = ', list (1) (i:i) ! a both! no bug is shown here by gfortran
t = list(1)(i:i) ! t = 'a'
t1 = list(1)(1:1) ! t1 = 'a' (character(1))
tt = list(1)(i:i) ! tt = 'a' (character(2))
write(*, *) 't use i:i = ', t, '| len = ', len(t)
write(*, *) 't1 use 1:1 = ', t1, '| len = ', len(t1)
write(*, *) 'tt = ', tt, '| len = ', len(tt)
write(*, *) 't == t1 is ', t == t1
print *
print *, "'ab' sliced by i:i == 'a' and == t and == tt"
write (*, *) list(1)(i:i) == 'a', & ! T
list(1)(i:i) == t, & ! T
list(1)(i:i) == tt ! T
print *
 
!! both agree on T F result
print *, "direct comparing of 1 char strings"
write(*,*) 'a' == (/ 'a', 'b' /)
write(*,*) (/'a', 'b' /) == 'a'
print *
 
!! T F
print *, "list(1)(1:1) == (/ 'a', 'b' /)"
write(*,*) list(1)(1:1) == (/ 'a', 'b' /)
print *, "char(1) t ('a') == char(2), dim(2) la ['a', 'b']"
write(*, *) t == la
print *
!! T F
print *, "list(1)(1:1) [char(2) 'a' sliced] == char(2)dim(2) sliced ['a', 'b']"
write(*,*) "1:1 1:1|", list(1)(1:1) == list(:)(1:1)
write(*,*) "i:i 1:1|", list(1)(i:i) == list(:)(1:1)
write(*,*) "i:i i:i|", list(1)(i:i) == list(:)(i:i)
write(*,*) "1:1 i:i|", list(1)(1:1) == list(:)(i:i)
print *
 
print *, "list(:)(1:1) == X" ! shows the error is someway "propagated" to X
write(*,*) "X is t |", list(:)(1:1) == t
write(*,*) "X is t1 |", list(:)(1:1) == t1
write(*,*) "X is 'a'|", list(:)(1:1) == 'a'
write(*,*) "X is tt |", list(:)(1:1) == tt
print *, "reference: (/ 'a', 'b' /) == tt"
write(*,*) (/'a', 'b'/) == tt
print *
 
print *, "casting to non parameter"
p = list(:)(1:1)
print *, "p = ", p, "| size(p) = ", size(p)
print *, "p == X"
write(*, *) "X is t |", p == t
write(*, *) "X is t1 |", p == t1
write(*, *) "X is tt |", p == tt
print *
!! same output for g95 and gfortran
print *, "checking diffs between char(1) and char(2)"
write(*,'(A,A)') 'ab', 'cd' !abcd
write(*,'(A,A)') tt, t1 !a a
write(*,'(A,A)') t1, tt !aa
 
end program test</lang>
 
:: I also suspect that the difference is that when we are using constant number, the slicing is done at compile time, while when there's a variable that must be evaluated, the slicing is done at runtime and problems arises for the "immutable" nature of the parameter. So as already said a work-around is to remove the parameter attribute...! &mdash;[[User:ShinTakezou|ShinTakezou]] 19:45, 27 May 2010 (UTC)