2013-03-15 25 views
6

C++ 'da, bir tam sayı veya kayan nokta türü olabilen x türünde T numaralı bir numaram olduğunu varsayalım. y < x'un tuttuğu en büyük y türünü T türünde bulmak istiyorum. Çözeltinin, hem tamsayılarla hem de kayan nokta sayılarıyla saydam olarak çalışacak şekilde ayarlanması gerekir. x'un zaten T'da temsil edilebilecek en küçük sayı olduğu kenar durumunu görmezden gelebilirsiniz.En Büyük Numara <x?

OLASI KULLANIM DURUMU: Bu soru da yerelleştirilmiş olarak işaretlendi, dolayısıyla daha genel olduğunu düşündüğüm bir kullanım durumu sağlamak istiyorum. OP'nin orijinal yazarı olmadığımı unutmayın.

struct lower_bound { 
    lower_bound(double value, bool open) : value(open? value+0.1 : value) {} 
    double value; 
    bool operator()(double x) { return x >= value; } 
}; 

Bu sınıf açık ya da kapalı olabilir, ki bu, bir alt sınır simüle:

bu yapı göz önünde bulundurun. Tabi ki, gerçekte (amaçlanan) yaşamda bunu yapamayız. Akan tüm gerçek sayılar olan S için hesaplama yapmak imkansızdır (veya en azından oldukça zor). S kayan nokta sayı dizisidir biz aslında sayılabilir seti ile ilgileniyor beri

enter image description here

Ancak, bu çok geçerli ilkedir; ve sonra açık veya kapalı bir sınır diye bir şey yoktur. Yani,> = lower_bound sınıfında yapılan> gibi terimlerle tanımlanabilir.

Kod sadeliği için açık bir alt sınırı taklit etmek için +0.1 kullandım. Tabii ki, 0.1 değeri, z değerleri olabilir, zira değerler < z < = değer + 0.1 veya değer + 0.1 == değeri kayan nokta temsilinde olabilir.

struct lower_bound { 
    lower_bound(double value, bool open) : open(open), value(value) {} 
    bool open; 
    double value; 
    bool operator()(double x) { return (open ? x > value : x>=value); } 

}; 

Ancak bu sizeof (LOWER_BOUND), büyük ve operatör olarak daha az etkilidir() ihtiyaçlar: Dolayısıyla @ Brett-Hale cevap çok yararlı :)

başka daha basit çözümü hakkında düşünebilir

olduğunu daha karmaşık bir ifade yürütmek. İlk uygulama gerçekten verimli ve bir yapı yerine basitçe bir çift olarak da uygulanabilir. Teknik olarak, ikinci uygulamayı kullanmanın tek nedeni, bir çiftin sürekli olduğunu varsaymaktır, oysa ki tahmin edilemez bir gelecekte olmayacaktır.

Umarım geçerli bir kullanım vakası yaratmış ve açıklamıştım ve orijinal yazarı rahatsız etmemiştim.

+1

bu Kesirli için ne olacağını bir örnek verebilir misiniz? Bu, '' mantısının bir bit kadar küçük ve üssü aynı olduğu anlamına mı geliyor? – angelatlarge

+3

27.5k kullanıcısından daha fazlasını bekliyorum. –

+0

Yaptınız mı? – Rapptz

cevap

11

C++ 11, siz <cmath> içinde std::nextafter kullanabilirsiniz varsa:

if (std::is_integral<T>::value) 
    return (x - 1); 
else 
    return std::nextafter(x, - std::numeric_limits<T>::infinity()); 
+0

[x-1.0, yüzer tipler için x değerine eşit olabilir ve çok sayıda sayı için gerçekleşir> = ~ 33554432] (http : //coliru.stacked-crooked.com/view? id = cc0ae3f34df4c559275ba1290458f077-61c3814520a8d4318f681038dc4b4da7) –

+0

@MooingDuck - evet teşekkür ederim, aceleciydi. ute hatası. –

+0

@BrettHale: Kolay gözetim yapmak için eminim, eminim kodumun her tarafında. –