C ++ 03 standardı, standardın C ++ 03 standardının taslağında (C ++ 03'e halka açık en yakın taslak standart N1804'tür ) Standart C Kütüphanesi dediği şey için C90 standardına dayanır. Normatif referanslar :1.2
ISO / IEC 9899: 1990 madde 7'de ve ISO / IEC 9899 / Amd.1: 1995 madde 7'de açıklanan kütüphane bundan böyle Standart C Kütüphanesi olarak adlandırılacaktır. 1)
Biz gidersek yuvarlak, lround C dokümantasyon, cppreference üzerinde llround biz görebilirsiniz yuvarlak ve ilgili fonksiyonlar parçası olan C99 ve böylece 03 veya öncesinde C ++ kullanılamayacaktır.
C ++ 11'de bu, C ++ 11'in C standart kitaplığı için C99 taslak standardına bağlı olması nedeniyle değişir ve bu nedenle std :: round ve integral dönüş türleri için std :: lround, std :: llround sağlar :
#include <iostream>
#include <cmath>
int main()
{
std::cout << std::round( 0.4 ) << " " << std::lround( 0.4 ) << " " << std::llround( 0.4 ) << std::endl ;
std::cout << std::round( 0.5 ) << " " << std::lround( 0.5 ) << " " << std::llround( 0.5 ) << std::endl ;
std::cout << std::round( 0.6 ) << " " << std::lround( 0.6 ) << " " << std::llround( 0.6 ) << std::endl ;
}
C99'dan başka bir seçenek de std :: trunc olacaktır :
Arg değerinden daha büyük olmayan en yakın tamsayıyı hesaplar.
#include <iostream>
#include <cmath>
int main()
{
std::cout << std::trunc( 0.4 ) << std::endl ;
std::cout << std::trunc( 0.9 ) << std::endl ;
std::cout << std::trunc( 1.1 ) << std::endl ;
}
C ++ 11 olmayan uygulamaları desteklemeniz gerekiyorsa, en iyi seçiminiz boost round, iround, lround, llround veya boost trunk kullanmak olacaktır .
Kendi raund versiyonunuzu yuvarlamak zordur
Kendinizi yuvarlamak , muhtemelen göründüğünden daha zor bir çabaya değmez : şamandırayı en yakın tam sayıya yuvarlama, bölüm 1 , Şamandırayı en yakın tam sayıya yuvarlama , bölüm 2 ve Yuvarlama şamandırasını en yakın tam sayıya yuvarlama, bölüm 3 açıklar:
Örneğin, uygulamanızı kullanan std::floor
ve ekleyen ortak bir rulo 0.5
tüm girdiler için çalışmaz:
double myround(double d)
{
return std::floor(d + 0.5);
}
Bunun başarısız olacağı girişlerden biri 0.49999999999999994
, ( canlı olarak görün ).
Diğer bir yaygın uygulama, bir kayan nokta tipinin bir integral tipine dökülmesini içerir; bu, integral parçasının hedef tipte temsil edilememesi durumunda tanımlanmamış davranışı uyarabilir. Bunu, taslak C ++ standart bölümü 4.9
Kayan-integral dönüşümlerden ( vurgu benim ) şöyle görebiliriz:
Kayan nokta türünün bir ön değeri, tamsayı türünün bir ön değerine dönüştürülebilir. Dönüşüm kısalır; yani kesirli kısım atılır. Kesilen değer hedef türünde gösterilemiyorsa, davranış tanımsızdır. [...]
Örneğin:
float myround(float f)
{
return static_cast<float>( static_cast<unsigned int>( f ) ) ;
}
Verilen std::numeric_limits<unsigned int>::max()
olduğu 4294967295
şu çağrı sonra:
myround( 4294967296.5f )
taşmaya neden olur ( canlı olarak görün ).
C (round) () 'i uygulamanın Muhtasar yolunun bu cevabına bakarak bunun ne kadar zor olduğunu görebiliriz. tek hassas şamandıra turu newlibs sürümünü referans hangi . Basit görünen bir şey için çok uzun bir işlevdir. Kayan nokta uygulamaları hakkında bilgi sahibi olmayan herkesin bu işlevi doğru bir şekilde uygulayabilmesi olası görünmemektedir:
float roundf(x)
{
int signbit;
__uint32_t w;
/* Most significant word, least significant word. */
int exponent_less_127;
GET_FLOAT_WORD(w, x);
/* Extract sign bit. */
signbit = w & 0x80000000;
/* Extract exponent field. */
exponent_less_127 = (int)((w & 0x7f800000) >> 23) - 127;
if (exponent_less_127 < 23)
{
if (exponent_less_127 < 0)
{
w &= 0x80000000;
if (exponent_less_127 == -1)
/* Result is +1.0 or -1.0. */
w |= ((__uint32_t)127 << 23);
}
else
{
unsigned int exponent_mask = 0x007fffff >> exponent_less_127;
if ((w & exponent_mask) == 0)
/* x has an integral value. */
return x;
w += 0x00400000 >> exponent_less_127;
w &= ~exponent_mask;
}
}
else
{
if (exponent_less_127 == 128)
/* x is NaN or infinite. */
return x + x;
else
return x;
}
SET_FLOAT_WORD(x, w);
return x;
}
Öte yandan, diğer çözümlerin hiçbiri kullanılamıyorsa, newlib iyi test edilmiş bir uygulama olduğundan potansiyel olarak bir seçenek olabilir.
std::cout << std::fixed << std::setprecision(0) << -0.9
, örneğin bunu yapabilirsiniz .