Bir C (++) programında en küçük negatif değeri temsil etmenin (örneğin negatif sonsuzluğu kullanmak için) standart ve / veya taşınabilir bir yolu var mı?
Float.h içindeki DBL_MIN, en küçük pozitif sayıdır.
Bir C (++) programında en küçük negatif değeri temsil etmenin (örneğin negatif sonsuzluğu kullanmak için) standart ve / veya taşınabilir bir yolu var mı?
Float.h içindeki DBL_MIN, en küçük pozitif sayıdır.
Yanıtlar:
-DBL_MAX
float.h içinde tanımlanan ANSI C'de .
-DBL_MAX
tam olarak gösterilebilir olması gerekir, bu nedenle FP donanımı bunu yapamazsa, uygulama bunun etrafında çalışmalıdır. 5.2.4.2.2 C99'daki kayan tiplerin <float.h> p2 karakteristiklerindeki kayan nokta modeline bakın (o zamandan beri başka bir yere taşınmış olabilir).
DBL_MAX
nedenle tam olarak (1 - b ^ −p) b ^ e_max, tam olarak gösterilebilir, en negatif sonlu değer tam olarak - (1 - b ^ −p) b ^ e_max, ve bu tam olarak olduğu için -DBL_MAX
, olumsuzlama DBL_MAX
da herhangi bir yuvarlama hatası getiremez.
Kayan nokta numaraları (IEEE 754) simetriktir, bu nedenle en büyük değeri ( DBL_MAX
veya numeric_limits<double>::max()
) temsil edebiliyorsanız , başına bir eksi işareti ekleyin.
Ve sonra harika yol:
double f;
(*((long long*)&f))= ~(1LL<<52);
C'de, kullanın
#include <float.h>
const double lowest_double = -DBL_MAX;
C ++ 11 öncesi sürümde
#include <limits>
const double lowest_double = -std::numeric_limits<double>::max();
C ++ 11 ve sonrasında, kullanın
#include <limits>
constexpr double lowest_double = std::numeric_limits<double>::lowest();
min()
İşlev C ++ 11'den önce mevcut değil miydi ? Yoksa bundan farklı bir değer -max()
mi? en.cppreference.com/w/cpp/types/numeric_limits
min
size büyüklük olarak en küçük pozitif değeri ve büyüklük olarak lowest
en büyük negatif değeri verdiğini görürsünüz . Evet, korkunç. C ++ standart kitaplığının parlak dünyasına hoş geldiniz :-P
.
float.h
. limits.h
tamsayılar içindir
Bunu dene:
-1 * numeric_limits<double>::max()
Referans: numeric_limits
Bu sınıf, temel türlerin her biri için uzmanlaşmıştır, üyeleri, derlediği belirli platformda türün sahip olduğu özellikleri tanımlayan farklı değerlere geri döner veya ayarlanır.
-numeric_limits<double>::max()
?
-1 * ...
da onu biraz daha netleştirmek için kullanılır.
Gerçek sonsuzluğu mu yoksa minimum sonlu değeri mi arıyorsunuz? İlki ise, kullanın
-numeric_limits<double>::infinity()
sadece eğer işe yarar
numeric_limits<double>::has_infinity
Aksi takdirde kullanmalısınız
numeric_limits<double>::lowest()
C ++ 11'de tanıtılan.
lowest()
Müsait değilse , geri dönebilirsiniz
-numeric_limits<double>::max()
lowest()
prensip olarak farklılık gösterebilir , ancak normalde uygulamada değildir.
-numeric_limits<double>::max()
pratikte çalışsa bile teoride tam olarak taşınabilir değildir.
C ++ 11'den itibaren kullanabilirsiniz numeric_limits<double>::lowest()
. Standarda göre, tam olarak aradığınız şeyi döndürür:
Başka sonlu değer y'nin olmadığı sonlu bir x değeri
y < x
.
Olduğu tüm uzmanlıklar için anlamlıdıris_bounded != false
.
Pek çok cevap var -std::numeric_limits<double>::max()
.
Neyse ki, çoğu durumda iyi çalışacaklar. Kayan nokta kodlama şemaları, bir mantisteki bir sayıyı ve bir üssü ayrıştırır ve bunların çoğu (örneğin, popüler IEEE-754 ) mantise ait olmayan ayrı bir işaret biti kullanır. Bu, yalnızca işareti çevirerek en büyük pozitifin en küçük negatife dönüştürülmesine izin verir:
Standart herhangi bir kayan nokta standardı empoze etmez.
Argümanımın biraz teorik olduğuna katılıyorum, ancak bazı eksantrik derleyici yapıcılarının, ikinin tamamlayıcısının bazı varyasyonlarında kodlanmış bir mantis ile devrim niteliğinde bir kodlama şeması kullanacağını varsayalım . İkinin tümleyen kodlaması simetrik değildir. örneğin işaretli 8 bitlik bir karakter için maksimum pozitif 127'dir, ancak minimum negatif -128'dir. Bu nedenle, bazı kayan nokta kodlamalarının benzer asimetrik davranışlar gösterdiğini hayal edebiliriz.
Bunun gibi herhangi bir kodlama şemasının farkında değilim, ancak asıl mesele şu ki , standart işaret çevirmenin istenen sonucu vereceğini garanti etmiyor . Bu yüzden bu popüler cevap (üzgünüm çocuklar!) Tamamen taşınabilir standart çözüm olarak kabul edilemez! / * en azından bunun numeric_limits<double>::is_iec559
doğru olduğunu iddia etmediyseniz değil * /
Asıl soru sonsuzlukla ilgilidir. Öyleyse neden kullanmıyorsun
#define Infinity ((double)(42 / 0.0))
IEEE tanımına göre? Elbette bunu reddedebilirsiniz.
numeric_limits<double>::has_infinity && ! numeric_limits<double>::traps
Bir C (++) programında en küçük negatif değeri temsil etmenin (örneğin negatif sonsuzluğu kullanmak için) standart ve / veya taşınabilir bir yolu var mı?
C yaklaşımı.
Çoğu uygulama +/- sonsuzlukları destekler, bu nedenle en negatif double
değerdir -INFINITY
.
#include <math.h>
double most_negative = -INFINITY;
Standart ve / veya taşınabilir bir yol var mı ....?
Şimdi başka durumları da düşünmemiz gerekiyor:
Basitçe -DBL_MAX
.
Bu durumda beklerdim, OP tercih ederdi -DBL_MAX
.
DBL_MAX
.Bu alışılmadık bir durumdur, muhtemelen OP'nin endişesi dışında. Ne zaman double
bir bir çift olarak kodlanır kayan nokta istenen aralığın / eksen sapmasını elde etmek için, (bakınız çift çift maksimum orada var) , normal double
ve belki de daha büyük bir de normal bir. Her ikisinin DBL_MAX
de en büyüğü, en büyük normale atıfta bulunulması gerekip gerekmediği konusunda tartışmalar gördüm .
Neyse ki bu ikili yaklaşım genellikle -sonsuzluğu içerir, bu nedenle en negatif değer kalır -INFINITY
.
Daha fazla taşınabilirlik için kod rotadan aşağı inebilir
// 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;
Float istisnalarını etkinleştirmediyseniz (ki bunu imho yapmamalısınız), basitçe şunu söyleyebilirsiniz:
double neg_inf = -1/0.0;
Bu, negatif sonsuzluk verir. Bir şamandıraya ihtiyacınız varsa, sonucu ya
float neg_inf = (float)-1/0.0;
veya tek duyarlıklı aritmetik kullanın
float neg_inf = -1.0f/0.0f;
Sonuç her zaman aynıdır, hem tek hem de çift kesinlikte negatif sonsuzluğun tam olarak bir temsili vardır ve beklediğiniz gibi birbirlerine dönüşürler.
-INFINITY
neg_inf
başlatıldığını fark edeceksiniz . Derleyici değeri hesaplamakla ilgilenecektir . Ve bunu bir maks. Hesaplamak için boş değer olarak kullandığınızda, ilk yineleme genellikle onun üzerine daha büyük bir değer yazacaktır. Yani performans pek sorun değil. Ve OP özellikle "örneğin negatif sonsuzluğu kullanmak" hakkında sorar ve gerçekten de buna tek doğru cevaptır. Doğru ve faydalı bir cevaba olumsuz oy verdiniz. inf
-inf