英特尔Fortran排序例程的开源版本
我正在尝试使用gfortran在GNU平台上编译一些专有的Fortran代码。有人知道例程英特尔Fortran排序例程的开源版本,fortran,gfortran,intel-fortran,Fortran,Gfortran,Intel Fortran,我正在尝试使用gfortran在GNU平台上编译一些专有的Fortran代码。有人知道例程sortqq()或qsort\u up()是否有开源的对应程序吗?libc包含qsort()。如果用Fortran为它编写绑定(c)接口,就可以调用它 首先,下面是一个示例模块,它提供了模仿专有功能的my_qsort包装器: $ cat sort.f90 module m use, intrinsic :: iso_c_binding implicit none private inter
sortqq
()或qsort\u up
()是否有开源的对应程序吗?libc包含qsort()。如果用Fortran为它编写绑定(c)接口,就可以调用它
首先,下面是一个示例模块,它提供了模仿专有功能的my_qsort包装器:
$ cat sort.f90
module m
use, intrinsic :: iso_c_binding
implicit none
private
interface
subroutine qsort(base, nel, width, compar) bind(c, name='qsort')
import c_size_t, c_int
implicit none
type(*), intent(inout) :: base(*)
integer(c_size_t), value :: nel
integer(c_size_t), value :: width
abstract interface
function compar_iface(a, b) bind(c)
import c_int, c_ptr
implicit none
integer(c_int) compar_iface
type(c_ptr), value :: a, b
end function
end interface
procedure(compar_iface) compar
end subroutine
end interface
interface my_qsort
module procedure my_qsort_int4
module procedure my_qsort_int8
module procedure my_qsort_real4
module procedure my_qsort_real8
end interface
public my_qsort
contains
subroutine my_qsort_int4(a, nel)
integer(c_int), intent(inout) :: a(*)
integer(4), value :: nel
call qsort(a, int(nel, c_size_t), c_sizeof(a(1)), less_int4)
end subroutine
subroutine my_qsort_int8(a, nel)
integer(c_long_long), intent(inout) :: a(*)
integer(4), value :: nel
call qsort(a, int(nel, c_size_t), c_sizeof(a(1)), less_int8)
end subroutine
subroutine my_qsort_real4(a, nel)
real(c_float), intent(inout) :: a(*)
integer(4), value :: nel
call qsort(a, int(nel, c_size_t), c_sizeof(a(1)), less_real4)
end subroutine
subroutine my_qsort_real8(a, nel)
real(c_double), intent(inout) :: a(*)
integer(4), value :: nel
call qsort(a, int(nel, c_size_t), c_sizeof(a(1)), less_real8)
end subroutine
function less_int4(a, b) result(result)
integer(c_int) result
type(c_ptr), value :: a, b
integer(c_int), pointer :: ap, bp
call c_f_pointer(a, ap)
call c_f_pointer(b, bp)
result = int(ap - bp, c_int)
end function
function less_int8(a, b) result(result)
integer(c_int) result
type(c_ptr), value :: a, b
integer(c_long_long), pointer :: ap, bp
call c_f_pointer(a, ap)
call c_f_pointer(b, bp)
result = int(ap - bp, c_int)
end function
function less_real4(a, b) result(result)
integer(c_int) result
type(c_ptr), value :: a, b
real(c_float), pointer :: ap, bp
call c_f_pointer(a, ap)
call c_f_pointer(b, bp)
result = int(ap - bp, c_int)
end function
function less_real8(a, b) result(result)
integer(c_int) result
type(c_ptr), value :: a, b
real(c_double), pointer :: ap, bp
call c_f_pointer(a, ap)
call c_f_pointer(b, bp)
result = int(ap - bp, c_int)
end function
end module
program main
use m
implicit none
integer(4) a(10)
real(4) b(4)
a = [ 2, 6 , 1, 3, 10, 9, 7, 8, 4, 5 ]
call my_qsort(a, 10)
print *, a
b = [ 2.0, 5.0, 1.0, -5.0 ]
call my_qsort(b, 4)
print *, b
end program
$ gfortran sort.f90
$ ./a.out
1 2 3 4 5 6 7 8 9 10
-5.00000000 1.00000000 2.00000000 5.00000000
$
我让您的示例工作,但当我尝试将其推广到我的特定情况时,编译器警告您的
less_real()
函数中的a-b
可能会导致转换中的值发生变化。我还得到了一系列接口不匹配错误:参数'a'(Type(*)/REAL(8))中的类型不匹配。
等是包含所有调用以及完整错误输出的GitHub要点。您知道这里发生了什么吗?a-b
警告在这种情况下是无害的,但是可以通过使用int()
函数进行显式转换来删除。至于类型不匹配错误,我以前版本的gfortran没有捕捉到。我已经在编辑中解决了这两个问题。