2013-02-24 39 views
6

Tôi đang tìm cách chống đạn để chuyển đổi các biến loại logic thành kiểu thực sẽ hoạt động trong cả ifort và gfortran. Các công trình sau đây trong ifort, nhưng không trong gfortran:Chuyển đổi loại hợp lý thành gấp đôi trong Fortran

logical :: a 
real :: b 
a = .true. 
b = dble(a) 

Lỗi ném vào gfortran là

b = dble(a) 
     1 
Error: 'a' argument of 'dble' intrinsic at (1) must be a numeric type 

Rõ ràng, .true. nên ánh xạ tới 1.d0 và .false. đến 0.d0. Cách tốt nhất để làm điều này là gì?

+0

Đối với giá trị của nó, nếu bạn bật ifort kiểm tra chuẩn nên khiếu nại. Lý do nó hoạt động là bộ xử lý có một phần mở rộng cho phép chuyển đổi ngầm của lô-gic thành số nguyên, tiêu chuẩn sau đó cung cấp cho việc chuyển đổi từ số nguyên sang thực. Lưu ý rằng khi bạn nói "rõ ràng" biểu diễn bên trong của .TRUE. sẽ trông hoàn toàn không có gì giống như giá trị thực 1.0, trong khi trên * một số bộ xử lý * biểu diễn bên trong của .TRUE. là chính xác giống như giá trị số nguyên của 1 (đặc biệt nếu logic mặc định và LOGICAL (C_BOOL) là cùng một biểu diễn). – IanH

+0

. = -1 cũng là phổ biến (tất cả các bit trong một số nguyên được đặt thành 1, trong phần bù của 2 = -1). – WaywiserTundish

Trả lời

6

Tôi không chắc liệu có một công cụ nội tại thực hiện việc này hay không. Tôi không biết tại sao ifort chấp nhận điều này, và tôi đoán rằng đó là một chức năng cụ thể của trình biên dịch.

tùy chọn này, đặc biệt vì bạn muốn điều này là bằng chứng đạn, là tạo chức năng của riêng bạn.

tôi đã không kiểm tra này, nhưng sau đây có thể làm việc:

double precision function logic2dbl(a) 
    logical, intent(in) :: a 

    if (a) then 
    logic2dbl = 1.d0 
    else 
    logic2dbl = 0.d0 
    end if 
end function logic2dbl 
+0

Bạn nên trả về giá trị dưới dạng tên hàm: 'logic2dbl = ...'. – sigma

+0

Ngoài ra, bạn nên thay thế .eq. với .eqv. Tôi sẽ chấp nhận khi câu trả lời là chính xác về cú pháp! – Guillochon

8

Ngoài viết một chức năng để xử lý việc này, bạn cũng có thể trực tiếp sử dụng chức năng hợp nhất nội tại: b = merge(1.d0, 0.d0, a). Hoặc bạn có thể viết một chương trình con được gán đã định nghĩa để thực hiện điều này, để bạn có thể chỉ cần gõ b = a.

0

Trong gfortran, tôi đang sử dụng TRANSFER nội tại cho loại công việc đó. Giả sử biến số nguyên my_int sau đó:

my_int = transfer(.false.,my_int) 

kết quả của my_int bằng 0 như mong đợi.

+2

OP đang yêu cầu các biến thực ... – lodo

+1

'realvar = transfer (logic, 1)' (chỉ cần đặt một số nguyên 1 cho khuôn) hoạt động (hoặc dường như). Bạn không chắc chắn cách di chuyển này mặc dù được đưa ra @WaywiserThu thập bình luận – agentp

Các vấn đề liên quan