Apakah ada cara standar dan / atau portabel untuk merepresentasikan nilai negatif terkecil (misalnya menggunakan tak terhingga negatif) dalam program C (++)?
DBL_MIN dalam float.h adalah bilangan positif terkecil .
Apakah ada cara standar dan / atau portabel untuk merepresentasikan nilai negatif terkecil (misalnya menggunakan tak terhingga negatif) dalam program C (++)?
DBL_MIN dalam float.h adalah bilangan positif terkecil .
Jawaban:
-DBL_MAX di ANSI C , yang didefinisikan di float.h.
-DBL_MAXharus benar-benar dapat direpresentasikan, jadi jika perangkat keras FP tidak mampu melakukannya, implementasinya harus mengatasinya. Lihat model floating-point di 5.2.4.2.2 Karakteristik tipe mengambang <float.h> p2 dari C99 (mungkin telah dipindahkan ke tempat lain sejak saat itu).
DBL_MAXpersis (1 - b ^ −p) b ^ e_max, yang dapat direpresentasikan secara tepat, nilai hingga paling negatif persis - (1 - b ^ −p) b ^ e_max, dan karena itu terjadi tepat -DBL_MAX, meniadakan DBL_MAXjuga tidak dapat menyebabkan kesalahan pembulatan.
Angka floating point (IEEE 754) adalah simetris, jadi jika Anda dapat mewakili nilai terbesar ( DBL_MAXatau numeric_limits<double>::max()), tambahkan saja tanda minus.
Dan kemudian adalah cara yang keren:
double f;
(*((long long*)&f))= ~(1LL<<52);
Di C, gunakan
#include <float.h>
const double lowest_double = -DBL_MAX;
Di C ++ pra-11, gunakan
#include <limits>
const double lowest_double = -std::numeric_limits<double>::max();
Di C ++ 11 dan seterusnya, gunakan
#include <limits>
constexpr double lowest_double = std::numeric_limits<double>::lowest();
min()fungsi tersedia sebelum C ++ 11? Atau apakah itu nilai yang berbeda dari -max()? en.cppreference.com/w/cpp/types/numeric_limits
minAnda mendapatkan nilai positif terkecil dalam besaran, dan lowestnilai negatif terbesar dalam besaran. Ya, itu mengerikan. Selamat datang di dunia pustaka standar C ++ yang brilian :-P.
float.h. limits.hadalah untuk bilangan bulat
Coba ini:
-1 * numeric_limits<double>::max()
Referensi: numeric_limits
Kelas ini dikhususkan untuk setiap tipe dasar, dengan anggotanya yang kembali atau disetel ke nilai berbeda yang menentukan properti yang dimiliki tipe dalam platform spesifik tempat ia dikompilasi.
-numeric_limits<double>::max()?
-1 * ...untuk membuatnya sedikit lebih jelas.
Apakah Anda mencari infinity aktual atau nilai terbatas minimal? Jika bekas, gunakan
-numeric_limits<double>::infinity()
yang hanya berfungsi jika
numeric_limits<double>::has_infinity
Jika tidak, Anda harus menggunakan
numeric_limits<double>::lowest()
yang diperkenalkan di C ++ 11.
Jika lowest()tidak tersedia, Anda dapat kembali ke
-numeric_limits<double>::max()
yang mungkin berbeda dari lowest()prinsipnya, tetapi biasanya tidak dalam praktiknya.
-numeric_limits<double>::max()bahkan jika itu berhasil dalam prakteknya tidak sepenuhnya portabel dalam teori.
Mulai dari C ++ 11 Anda dapat menggunakan numeric_limits<double>::lowest(). Menurut standar, ini mengembalikan persis apa yang Anda cari:
Nilai hingga x sedemikian sehingga tidak ada nilai hingga lainnya y di mana
y < x.
Berarti untuk semua spesialisasi di dalamnyais_bounded != false.
Ada banyak jawaban yang muncul -std::numeric_limits<double>::max().
Untungnya, mereka akan bekerja dengan baik di sebagian besar kasus. Skema pengkodean titik mengambang menguraikan angka dalam mantissa dan eksponen dan kebanyakan dari mereka (misalnya IEEE-754 yang populer ) menggunakan bit tanda yang berbeda, yang bukan milik mantissa. Ini memungkinkan untuk mengubah positif terbesar menjadi negatif terkecil hanya dengan membalik tandanya:
Standar tersebut tidak memberlakukan standar floating point.
Saya setuju bahwa argumen saya sedikit teoretis, tetapi anggaplah beberapa pembuat kompilator yang sangat baik akan menggunakan skema pengkodean revolusioner dengan mantissa yang dikodekan dalam beberapa variasi pelengkap dua . Pengkodean komplemen Two tidak simetris. misalnya untuk karakter 8 bit bertanda positif maksimum 127, tetapi negatif minimum adalah -128. Jadi kita bisa membayangkan beberapa pengkodean floating point menunjukkan perilaku asimetris yang serupa.
Saya tidak mengetahui skema pengkodean seperti itu, tetapi intinya adalah bahwa standar tidak menjamin bahwa tanda membalik menghasilkan hasil yang diinginkan . Jadi jawaban populer ini (maaf guys!) Tidak dapat dianggap sebagai solusi standar yang sepenuhnya portabel! / * setidaknya tidak jika Anda tidak menegaskan bahwa numeric_limits<double>::is_iec559itu benar * /
Pertanyaan asli menyangkut ketidakterbatasan. Jadi, mengapa tidak digunakan
#define Infinity ((double)(42 / 0.0))
menurut definisi IEEE? Anda tentu saja dapat meniadakannya.
numeric_limits<double>::has_infinity && ! numeric_limits<double>::traps
Apakah ada cara standar dan / atau portabel untuk merepresentasikan nilai negatif terkecil (misalnya menggunakan tak terhingga negatif) dalam program C (++)?
Pendekatan C.
Banyak implementasi mendukung +/- tak terhingga, jadi nilai yang paling negatif doubleadalah -INFINITY.
#include <math.h>
double most_negative = -INFINITY;
Apakah ada cara standar dan / atau portabel ....?
Sekarang kita juga perlu mempertimbangkan kasus lain:
Sederhana -DBL_MAX.
Saya berharap dalam kasus ini, OP lebih suka -DBL_MAX.
DBL_MAX.Ini adalah kasus yang tidak biasa, kemungkinan besar di luar perhatian OP. Ketika doubledikodekan sebagai sepasang titik mengambang untuk mencapai kisaran / presesi yang diinginkan, (lihat ganda-ganda ) terdapat normal maksimum doubledan mungkin yang lebih besar dari normal . Saya telah melihat perdebatan jika DBL_MAXharus mengacu pada normal terbesar , dari yang terbesar dari keduanya.
Untungnya pendekatan berpasangan ini biasanya menyertakan -infinity, sehingga nilai paling negatif tetap ada -INFINITY.
Untuk portabilitas lebih, kode dapat menyusuri rute
// HUGE_VAL is designed to be infinity or DBL_MAX (when infinites are not implemented)
// .. yet is problematic with unsigned infinity.
double most_negative1 = -HUGE_VAL;
// Fairly portable, unless system does not understand "INF"
double most_negative2 = strtod("-INF", (char **) NULL);
// Pragmatic
double most_negative3 = strtod("-1.0e999999999", (char **) NULL);
// Somewhat time-consuming
double most_negative4 = pow(-DBL_MAX, 0xFFFF /* odd value */);
// My suggestion
double most_negative5 = (-DBL_MAX)*DBL_MAX;
Jika Anda tidak mengaktifkan pengecualian float (yang seharusnya tidak Anda imho), Anda cukup mengatakan:
double neg_inf = -1/0.0;
Ini menghasilkan ketidakterbatasan negatif. Jika Anda membutuhkan pelampung, Anda bisa melemparkan hasilnya
float neg_inf = (float)-1/0.0;
atau gunakan aritmatika presisi tunggal
float neg_inf = -1.0f/0.0f;
Hasilnya selalu sama, persis ada satu representasi tak terhingga negatif dalam presisi tunggal dan ganda, dan keduanya saling mengubah seperti yang Anda harapkan.
-INFINITY
neg_infdiinisialisasi ke nilai konstan . Kompiler akan menghitung infnilainya. Dan saat Anda menggunakannya sebagai nilai null untuk menghitung maks, iterasi pertama biasanya akan menimpanya dengan nilai yang lebih besar. Yaitu kinerja hampir tidak menjadi masalah. Dan OP bertanya secara khusus tentang "misalnya menggunakan tak terhingga negatif", dan -infmemang satu-satunya jawaban yang benar untuk ini. Anda tidak menyukai jawaban yang benar dan berguna.