2009-08-26 17 views
14

int to zazwyczaj 32 bity, ale w standardzie int nie ma gwarantowanej stałej szerokości. Jeśli więc chcemy 32-bitowego int, dołączamy stdint.h i używamy int32_t.Liczby zmiennoprzecinkowe o stałej szerokości w C/C++

Czy istnieje odpowiednik dla elementów pływających? Zdaję sobie sprawę, że jest to nieco bardziej skomplikowane w przypadku pływaków, ponieważ nie są one przechowywane w jednorodny sposób, tj. Znak, wykładnik, znaczenie. Chcę tylko double, który jest gwarantowany do przechowywania w 64 bitach z 1 bitem znakowym, 10-bitowym wykładnikiem i 52/53 bit significand (w zależności od tego, czy policzysz ukryty bit).

+0

Zazwyczaj liczba bitów dla int jest potrzebna, ponieważ koduje jakieś flagi obiektów. Dlaczego potrzebujesz gwarancji precyzji swoich pływaków? W większości przypadków widziałem, że ludzie mają tendencję do zawyżania znaczenia wielkości zmiennych losowych. Często lepiej jest używać domyślnego rozmiaru słowa komputera niż próbować wycisnąć 3 bajty pamięci lub dowolnie używać wartości 32-bitowych. –

+0

@ Andrew-Khosravian Piszę język skryptowy i chciałbym móc zapewnić moim użytkownikom dostęp do gwarancji rozmiaru. Dzięki temu kod napisany w moim języku skryptowym jest bardziej przenośny. – Imagist

+2

Przenośność jest w porządku, ale musisz narysować gdzieś linię - w końcu prawdopodobnie nie spodziewasz się, że twój język skryptowy będzie działał na PDP-11. Bardzo niewiele platform nie obsługuje IEEE 754, a jeśli jest to obsługiwane, to jest rozsądnym założeniem, że double jest w rzeczywistości 64 bitami (ponieważ jest to wartość zmiennoprzecinkowa * podwójna *) - i poza szansą, że nie jest , zbuduj kontrolę poprawności, aby użytkownicy mogli ją zgłosić i możesz obsługiwać tę platformę osobno. Jeśli platforma nie obsługuje IEEE 754, i tak nie otrzymasz tej reprezentacji, chyba że sam ją wdrożysz. –

Odpowiedz

3

Zgodnie z the current C99 draft standard, załącznik F, który powinien być podwójny. Oczywiście zakłada to, że kompilatory spełniają tę część normy.

Dla C++ sprawdziłem wersję roboczą 0x i wersję roboczą dla wersji standardowej z 1998 r., Ale nic nie wskazuje na reprezentację taką jak część standardu C99, poza boolem w numeric_limits, który określa, że ​​IEEE 754/IEC 559 jest używany na tej platformie, jak wspomina Josh Kelley.

Jednak niewiele platform nie obsługuje IEEE 754 - generalnie nie opłaca się zaprojektować innego formatu zmiennoprzecinkowego, ponieważ IEEE 754 jest dobrze zdefiniowany i działa całkiem przyjemnie - a jeśli jest obsługiwany, to jest rozsądne założenie, że podwójne jest w istocie 64 bitami (wywołania IEEE 754-1985 formatują podwójną precyzję, więc ma to sens).

Przy braku szansy, że podwójne nie jest podwójną precyzją, należy utworzyć kontrolę poprawności, aby użytkownicy mogli ją zgłosić i można obsługiwać tę platformę oddzielnie. Jeśli platforma nie obsługuje IEEE 754, i tak nie otrzymasz tej reprezentacji, chyba że sam ją wdrożysz.

+0

A co z C++? – Imagist

+0

Nie zgadzam się, że IEEE 754 działa całkiem nieźle, jest dobrze okopcony, więc niewiele można zrobić o ot. Zgadzam się, że to, czego chcesz, jest podwójne i chcesz dodać kontrolę poprawności, która nie powiedzie się, jeśli ktoś znajdzie kompilator, który ma podwójny niewłaściwy rozmiar. –

+0

@dwelch: Nie twierdzę, że nie ma w tym żadnej części problemów lub że zawsze jest najlepszym wyborem, ale jeśli nie ma potrzeby, aby być wyjątkowo precyzyjnym lub w inny sposób mieć bardzo wyspecjalizowane potrzeby, jeśli chodzi o point, IEEE 754 ma tendencję do robienia tego, nie będąc wyjątkowo powolnym. –

0

Niestety, nie jest to gwarantowane. Musisz sprawdzić numeric_limits<T> w .

Ale jeszcze raz, nigdy nie słyszałem o realizacji, w której podwójne nie było 64 bitów. Jeśli chcesz po prostu założyć, prawdopodobnie uszło ci to na sucho.

1

Inną kwestią jest reprezentacja liczb zmiennoprzecinkowych. Zwykle jest to oparte na sprzęcie, na którym pracujesz (ale nie zawsze). Większość systemów używa standardów IEEE 754 Float point, ale inne mogą również posiadać własne standardy (przykładem może być komputer VAX).

Wikipedia wyjaśnieniu IEEE 754 http://en.wikipedia.org/wiki/IEEE_754-2008

1

Nie ma zmienność pływaka/podwójne, że jestem świadomy. Pływak ma 32 bity był przez wieki i dwukrotnie został 64. Pływające semantyka punktowe są dość skomplikowane, ale nie istnieją stałe w

#include <limits> 

boost.numeric.bounds jest prostszy interfejs, jeśli nie trzeba wszystkiego w std :: numeric_limits

+0

To nie jest prawdą na wielu platformach. – Imagist

+0

Widziałem jednego kompilatora (LCC?), Który wykonywał zarówno typy "float", jak i "double" 64-bitowe. – dan04

3

Chociaż nie znam typu gwarantującego określony rozmiar i format, w C++ dostępnych jest kilka opcji. Możesz użyć nagłówka <limits> i jego szablonu klasy std::numeric_limits, aby określić rozmiar danego typu, std::numeric_limits::digits mówi liczbę bitów w mantysie, a std::numeric_limits::is_iec559 powinien powiedzieć, czy typ jest zgodny z formatem IEEE. (Przykładowy kod manipulujący numerami IEEE na poziomie bitów znajduje się w szablonie klasy FloatingPoint w teście Google Test: gtest-internal.h.)

-3

Jednym z największych problemów związanych z tego rodzaju "typami o stałej szerokości" jest to, że tak łatwo można pomylić. Prawdopodobnie nie chcesz 32-bitowej liczby całkowitej. Jaki jest sens? Chcielibyśmy, aby był typem całkowitym, który może przechowywać co najmniej 1 >> 31. To jest long int. Nie potrzebujesz do tego nawet <stdint.h>.

Podobnie, język skryptowy może implementować typ FP, która będzie pracować tak długo, jak C++ float bazowego jest przynajmniej 32 bitów. Zauważ, że to nadal nie zapewnia dokładnego zachowania. Jestem całkiem pewien, że C++ nie gwarantuje, że -1.0/-3.0==1.0/3.0

+0

Nie, zdecydowanie chcę 32-bitowej liczby całkowitej. Istnieje wiele języków, które gwarantują rozmiary ich podstawowych typów (C# i Java to dwa przykłady). "Punktem", jak to nazywasz, jest konsekwentne zachowanie na wszystkich platformach. – Imagist

+0

Niestety, brakuje ci punktu. Chcesz, aby twój język skryptowy miał typ dokładnie 32-bitowy.To w żaden sposób nie wymaga użycia C++ o dokładnie 32 bitach. Prawdopodobnie chcesz również zagwarantować przepełnienie, zachowanie gwarantujące%, itp. Więc i tak będziesz ponownie stosować matematykę. To banalne, aby uczynić ten matah modulo 2^32. – MSalters

+1

Nie, to jest 'int_least32_t', * not *' long int'. – dan04

Powiązane problemy