Tôi sử dụng std::complex<>trong các chương trình của mình và phải chiến đấu với cờ trình biên dịch và cách khắc phục cho mỗi trình biên dịch hoặc trình biên dịch mới. Tôi sẽ cố gắng kể lại những trận đánh này theo thứ tự thời gian:
std::norm| z|2| z|-ffast-math
- Trình biên dịch intel icc trên linux (hoặc trình liên kết) được biên dịch
std::argthành không chọn theo các cấu hình nhất định (tương thích liên kết với một phiên bản gcc cụ thể). Vấn đề xuất hiện trở lại quá thường xuyên, do đó std::argphải được thay thế bằng atan2(imag(),real()). Nhưng tất cả quá dễ dàng để quên điều này khi viết mã mới.
- Loại
std::complexsử dụng các quy ước cuộc gọi khác nhau (= ABI) so với loại phức hợp C99 tích hợp và loại phức hợp Fortran tích hợp cho các phiên bản gcc mới hơn.
- Các
-ffast-mathtương tác cờ biên dịch với việc xử lý các trường hợp ngoại lệ điểm nổi theo những cách bất ngờ. Điều gì xảy ra là trình biên dịch kéo các bộ phận ra khỏi các vòng lặp, do đó gây ra division by zerongoại lệ khi chạy. Những ngoại lệ này sẽ không bao giờ xảy ra trong vòng lặp, bởi vì sự phân chia tương ứng đã không diễn ra do logic xung quanh. Đó là một điều thực sự tồi tệ, bởi vì đó là một thư viện được biên dịch tách biệt với chương trình sử dụng xử lý ngoại lệ dấu phẩy động (sử dụng các cờ biên dịch khác nhau) và gặp phải các vấn đề này (các đội tương ứng đang ngồi ở các khu vực đối diện trên thế giới, vì vậy vấn đề này thực sự gây ra rắc rối xấu). Điều này đã được giải quyết bằng cách thực hiện tối ưu hóa được sử dụng bởi trình biên dịch bằng tay cẩn thận hơn.
- Thư viện đã trở thành một phần của chương trình và không còn sử dụng
-ffast-mathcờ biên dịch. Sau khi nâng cấp lên phiên bản gcc mới hơn, hiệu suất giảm do yếu tố rất lớn. Tôi đã không điều tra vấn đề này một cách chi tiết, nhưng tôi sợ nó có liên quan đến C99 Phụ lục G . Tôi phải thừa nhận rằng tôi hoàn toàn bối rối với định nghĩa nhân số kỳ lạ này cho các số phức và thậm chí dường như còn tồn tại các phiên bản khác nhau của điều này với tuyên bố rằng các phiên bản khác bị nhầm lẫn. Tôi hy vọng rằng -fcx-limited-rangecờ biên dịch sẽ giải quyết vấn đề, bởi vì dường như có một vấn đề khác liên quan đến -ffast-mathphiên bản gcc mới hơn này.
- Các
-ffast-mathlá cờ biên dịch làm cho hành vi của NaNhoàn toàn không thể đoán trước cho các phiên bản mới hơn của gcc (thậm chí isnanbị ảnh hưởng). Cách giải quyết duy nhất dường như là để tránh mọi sự xuất hiện NaNtrong chương trình, đánh bại mục đích cho sự tồn tại của NaN.
Bây giờ bạn có thể hỏi liệu tôi có kế hoạch từ bỏ các loại phức tạp tích hợp không và std::complexvì những lý do này. Tôi sẽ ở lại với các loại tích hợp, miễn là tôi ở lại với C ++. Trong trường hợp C ++ nên quản lý để trở nên hoàn toàn không sử dụng được cho máy tính khoa học, tôi muốn xem xét chuyển sang một ngôn ngữ quan tâm nhiều hơn đến các vấn đề liên quan đến điện toán khoa học.
zlà một biểu thức vế trái của loại cvstd::complex<T>sau đóreinterpret_cast<cv T(&)[2]>(z)vàreinterpret_cast<cv T(&)[2]>(z)[0]sẽ chỉ định một phần thực sự củaz, vàreinterpret_cast<cv T(&)[2]>(z)[1]sẽ chỉ định phần ảo củaz. Mảng số phức cũng được giải quyết.