Saya berasumsi bahwa abs
dan fabs
berperilaku berbeda saat menggunakan math.h
. Tetapi ketika saya menggunakan just cmath
and std::abs
, apakah saya harus menggunakan std::fabs
atau fabs
? Atau bukankah ini didefinisikan?
Saya berasumsi bahwa abs
dan fabs
berperilaku berbeda saat menggunakan math.h
. Tetapi ketika saya menggunakan just cmath
and std::abs
, apakah saya harus menggunakan std::fabs
atau fabs
? Atau bukankah ini didefinisikan?
Jawaban:
Di C ++, itu selalu cukup untuk digunakan std::abs
; itu kelebihan beban untuk semua tipe numerik.
Di C, abs
hanya bekerja pada integer, dan Anda membutuhkan fabs
nilai floating point. Ini tersedia dalam C ++ (bersama dengan semua pustaka C), tetapi tidak perlu menggunakannya.
int
versi dari perpustakaan C, ada overload untuk long
, float
, double
dan long double
. Klausul 26.2.7 juga mendefinisikan kelebihan beban complex
.
std::
dan hanya menggunakan abs
, kode Anda akan berfungsi seperti yang diharapkan di windows tetapi akan menggunakan int
versi di linux, yang bisa sangat sulit untuk di-debug.
Masih boleh digunakan fabs
untuk double
dan float
argumen. Saya lebih suka ini karena ini memastikan bahwa jika saya secara tidak sengaja std::
melepas abs
, bahwa perilaku tetap sama untuk input floating point.
Saya hanya menghabiskan 10 menit men-debug masalah ini, karena kesalahan saya sendiri dalam menggunakan, abs
bukan std::abs
. Saya berasumsi bahwa using namespace std;
akan menyimpulkan std::abs
tetapi tidak, dan sebagai gantinya menggunakan versi C.
Bagaimanapun, saya percaya itu baik untuk digunakan fabs
daripada abs
untuk input floating-point sebagai cara untuk mendokumentasikan niat Anda dengan jelas.
std::abs
tampaknya selalu dipanggil (dan bukan versi C abs
) saat menelepon abs
selama using namespace std;
dijelaskan di awal. Saya tidak tahu apakah ini khusus kompiler.
Ada satu alasan lagi untuk merekomendasikan std::fabs
input floating-point secara eksplisit.
Jika Anda lupa menyertakan <cmath>, Anda std::abs(my_float_num)
bisa jadi std::abs(int)
bukan std::abs(float)
. Sulit untuk diperhatikan.
"abs" dan "fabs" hanya identik untuk tipe float C ++, jika dapat diterjemahkan tanpa pesan overload yang ambigu.
Saya menggunakan g ++ (g ++ - 7). Bersama dengan penggunaan template dan terutama saat menggunakan mpreal, ada kasus dengan pesan "ambiguous overload" yang keras - abs(static_cast<T>(x))
tidak selalu menyelesaikannya. Ketika abs tidak ambigu, ada kemungkinan fabs bekerja seperti yang diharapkan. Untuk sqrt saya tidak menemukan jalan keluar yang sederhana.
Sejak berminggu-minggu saya berjuang keras di C ++ "bukan masalah yang ada". Saya memperbarui program C ++ lama ke C ++ 14 untuk penggunaan template yang lebih banyak dan lebih baik daripada sebelumnya. Seringkali parameter template yang sama dapat berupa tipe float atau kompleks standar atau tipe kelas apa pun. Mengapa, long double bertindak agak lebih masuk akal daripada tipe lainnya. Semua berfungsi, dan saya telah memasukkan mpreal sebelumnya. Kemudian saya mengatur tipe float default saya ke mpreal dan mengalami banjir kesalahan sintaks. Itu memberi ribuan kelebihan yang ambigu misalnya untuk abs dan sqrt, menangis untuk solusi yang berbeda. Beberapa membutuhkan fungsi bantuan yang kelebihan beban, tetapi di luar templat. Harus mengganti seribu penggunaan 0,0L dan 1,0L secara individual dengan tipe konstan yang tepat menggunakan Nol atau Satu atau type_cast - definisi konversi otomatis tidak mungkin karena ambiguitas.
Hingga Mei saya menemukan adanya konversi implisit sangat bagus. Tetapi jauh lebih sederhana itu akan menjadi tanpa apapun, dan memiliki konstanta tipe simpan dengan type_casts eksplisit yang aman ke tipe konstan standar lainnya.