Czy w językach, w których niedozwolone jest podkreślanie literałów całkowitych , dobrym pomysłem jest utworzenie stałej dla 1 miliarda? np. w C ++:
size_t ONE_BILLION = 1000000000;
Z pewnością nie powinniśmy tworzyć stałych dla małych liczb, takich jak 100. Ale przy 9 zerach można łatwo pominąć zero lub dodać dodatkową w kodzie:
tv_sec = timeInNanosec / 1000000000;
tv_nsec = timeInNanosec % 1000000000;
coding-style
Martin C. Martin
źródło
źródło
1e9
,10^9
lub1_000_000_000
jeśli języka używasz obsługuje.Odpowiedzi:
Większość języków ma zapis wykładniczy. Milion to
1e6
(1 razy 10 do potęgi 6). Zasadniczo rozwiązuje to problem jeszcze lepiej niż większość propozycji tutaj.Jednak w wielu językach podobnych do C notacja naukowa definiuje typ zmiennoprzecinkowy , co jest niefortunne, jeśli naprawdę potrzebujesz int. Możesz jednak z łatwością wpisać tę stałą, aby uniknąć niejawnych konwersji w formule.
n / int(1e9)
podzieliłby się przez miliard.W twoim przykładzie, dotyczącym wielkości fizycznych (czas w nanosekundach), ogólnie zadałbym sobie pytanie, czy liczba całkowita jest właściwym typem. W rzeczywistości zmiennoprzecinkowa
double
może być lepiej dopasowana do mierzalnych wielkości (chociaż są oczywiście przypadki, w których wolisz along long
).źródło
long long
zakresu.Zamiast tego utwórz NANOSECONDS_IN_ONE_SECOND jako to, co reprezentuje.
Lub krótsza, lepsza nazwa, jeśli możesz o niej pomyśleć.
źródło
Nanoseconds_Per_Second
ale jest to, moim zdaniem, poprawna odpowiedź.NANOSECONDS
nie ma znaczenia, ponieważ nie można powiedzieć, do czego ma się odnosić. PodobnieNANOSECONDS_PER_MICROSECOND
jest podobna poprawna stała, która ma sens.1mm/1m = 1000
, co jest dokładnie tym, co się tutaj robi.NS_PER_SEC
powinno być oczywiste dla każdego, kto powinien mieć do czynienia z nanosekundami.Stałe mają oznaczać liczby. Nie ma żadnego dodatkowego znaczenia w
ONE_BILLION
celu1000000000
. W rzeczywistości sprawia, że jest to bardziej mylące, ponieważ w różnych językach naturalnych miliard oznacza coś innego (tysiąc milionów lub milion milionów)! Jeśli chcesz napisać to krócej, istnieje duże prawdopodobieństwo, że Twój język programowania pozwala na stosowanie notacji naukowej, tj1e9
. W przeciwnym razie zgadzam się z @JohnB, że ta liczba naprawdę oznacza liczbę nanosekund na sekundę, więc nazwij to.źródło
W przypadku jednego lub dwóch zastosowań użyłbym konwencji:
Jest to całkowicie zrozumiałe, kompiluje się na stałe i ciężko jest popsuć.
Jest to również bardzo przydatne w przypadkach takich jak:
gdzie łatwo zauważyć, że mówimy o jednym dniu w ciągu kilku sekund.
źródło
instance.Time = ...
, ale potem go(1000 * 1000 * 1000)
jest typuint
, który musi mieć tylko 16 bitów, więc może się przepełnić. Możesz pisać,(1000L * 1000L * 1000L)
aby tego uniknąć.Długość wartości nie jest tym, co określa, czy stała jest potrzebna, czy nie.
Używasz stałych, aby unikać magicznych liczb , a nie pisać.
Na przykład są to doskonale poprawne stałe:
Posługiwać się:
(próbki kodu są w Javie, przetłumacz na swój ulubiony język)
źródło
Amerykański czy europejski miliard?
(lub pod względem technicznym miliard w krótkiej lub długiej skali - jeden to 1000 milionów, drugi to milion milionów).
Biorąc pod uwagę to zamieszanie, powiedziałbym, że tak - sensowne jest zdefiniowanie go raz i pozostanie z nim, podobnie dotyczy każdej stałej, na którą trzeba uzgodnić definicję - zdefiniować raz.
źródło
Powody, dla których nie
Po pierwsze, oto powód, dla którego nie należy pisać podkreślników ani używać żadnej sztuczki, aby to zasymulować: utrudnia to znalezienie stałych w kodzie. Załóżmy, że jakiś program wykazuje gdzieś w działaniu zakodowaną wartość 1500000 dla jakiegoś parametru. Chcę wiedzieć, gdzie w kodzie źródłowym programu tak się dzieje, więc szukam kodu
1500000
i nic nie znajduję. Czemu? Może być w systemie szesnastkowym (ale dlaczego tak okrągłej liczby dziesiętnej). Bez mojej wiedzy stała jest tak naprawdę zapisana jako1_500_000
. Potrzebowałem wyrażenia regularnego1_?500_?000
.Prowadzenie postaci w komentarzu
To, że jeden rodzaj pomocy wizualnej nie jest dostępny lub nie chcemy jej używać z powyższego powodu, nie oznacza, że nie możemy skorzystać z dwóch wymiarów pliku tekstowego, aby stworzyć alternatywną pomoc wizualną:
Dzięki temu możemy łatwo przekonać się, że istnieją trzy grupy trzech zer. Jednak nadal możemy grepować kod źródłowy
1000000000
i go znaleźć.Kolorowanie składni
Edytor tekstu z programowalnym kolorowaniem składni może być utworzony w celu grupowania cyfr cyfr w stałych liczbowych naprzemiennymi kolorami dla lepszej czytelności. Nie musimy nic robić w kodzie.
Przetwarzanie wstępne: C, C ++, Cel C
Teraz, jeśli naprawdę chcemy przecinków między cyframi, w C i C ++ możemy użyć przetwarzania wstępnego:
Działa dla liczb takich jak
TH(1,234,567,890)
.Makro podobne do TH może również działać z wklejaniem tokenów, a nie z arytmetyką. W preprocesorze C
##
operator binarny („wklej token”) może być użyty w ciele makra w celu wklejenia dwóch operandów w jeden token. Jeden lub oba operandy mogą być argumentami makr. Minusem tutaj (stwarzającym dla nas ryzyko) jest to, że jeśli wynikowa catenacja nie jest prawidłowym tokenem, zachowanie jest niezdefiniowane.Teraz
Istnieją programy typu C, które wklejają identyfikatory i używają wyników do nazwania zmiennych globalnych i funkcji, i są okropne w pracy, ponieważ są odporne na narzędzia takie jak narzędzia GNU i ctag.
źródło
Tak, to brzmi jak rozsądny pomysł. Błędy DIGIT off-by-one są jeszcze gorsze niż niesławne błędy off-by-one. Chociaż może to powodować zamieszanie dla innych osób (w tym twojego przyszłego ja) w czytaniu kodu.
Bardziej objaśniająca nazwa, taka jak NANOSEC_PER_SEC, wydaje się dobra, ponieważ zwiększyłaby przejrzystość w przypadku użycia jej na czas. Jednak nie ma sensu używać go w kontekstach innych niż czas i byłoby niepraktyczne tworzyć osobne 1 000 000 000 dla każdej sytuacji.
To, co naprawdę chcesz zrobić, na pierwszy rzut oka głupie, to „podzielić na sekundę”. Pozostawia to NANO_PER, który jest nie tylko niezależny od języka (10 ^ 9 w Ameryce i Europie), ale także niezależny od sytuacji (bez ograniczeń jednostek), i jest łatwy do pisania i czytania.
źródło
Ogólnie rzecz biorąc, złym pomysłem jest używanie stałych skalarnych do konwersji jednostek, a jeśli odkryjesz, że tworzysz stałe dla takich rzeczy, robisz konwersję w zbyt wielu miejscach.
Gdy masz ilość jednej jednostki (powiedzmy 10 sekund) i chcesz przekonwertować na inną jednostkę (np. Nanosekundy); to jest właśnie czas na użycie systemu pisma w twoim języku, aby upewnić się, że jednostki są skalowane tak, jak chcesz.
Dokonać funkcja ma
Nanoseconds
parametr i zapewnić operatorom konwersji i / lub konstruktorów w tej klasieSeconds
,Minutes
lub co-ma-ty. To gdzie sięconst int
lub#define
czy1e9
widać w innych odpowiedzi należy.Pozwala to uniknąć przemieszczania się zmiennych o niejednoznacznych jednostkach wokół kodu; i zapobiega całemu zestawowi błędów, od których zastosowano niewłaściwe mnożenie / dzielenie, lub zostało już zastosowane, lub ilość faktycznie była odległością zamiast czasu, lub ...
Ponadto w takich klasach dobrze jest tworzyć konstrukcje ze zwykłego scalarsprivate i używać statycznego „MakeSeconds (int)” lub podobnego, aby zniechęcić do niechlujnego używania nieprzezroczystych liczb.
Dokładniej w twoim przykładzie, w C ++ sprawdź Boost.Chrono .
źródło
Osobiście nie uważałbym za dobrą praktykę tworzenia stałej, chyba że musi to być stała. Jeśli będzie w wielu miejscach, a zdefiniowanie go w górnej części pliku do modyfikacji / lub testowania będzie przydatne, to absolutnie przydatne.
Jeśli to tylko dlatego, że trudno jest pisać? w takim razie nie.
Osobiście, jeśli mam kod innej osoby, który ma stałą zdefiniowaną, ogólnie uważam to za ważny aspekt kodu. Np. Tcp utrzymuje przy życiu liczniki, maksymalna dozwolona liczba połączeń. Gdybym musiał go debugować, prawdopodobnie poświęciłbym temu wiele niepotrzebnej uwagi, próbując dowiedzieć się, dlaczego / gdzie jest używany.
źródło
Kiedy pomyślisz o tym, dlaczego w tytule pytania napisałeś „1 miliard” zamiast „1000000000”, zrozumiesz, dlaczego odpowiedź brzmi „tak”.
źródło
Nie twórz stałej dla swoich wielkich literałów. Potrzebowałbyś stałej dla każdego takiego dosłowności, co jest (moim zdaniem) kompletnym żartem. Jeśli desperacko potrzebujesz uczynić literały bardziej zrozumiałymi bez pomocy takich rzeczy jak podświetlanie składni, możesz (choć nie chciałbym) tworzyć funkcji lub makr, aby uczynić twoje życie „łatwiejszym”:
źródło
Zrobiłbym to:
lub
const int
SciMega = 1000 * 1000; const intSciGiga = 1000 *SciMega;Jeśli chodzi o liczbę nanosekund na sekundę: nano jest „odwrotnością” giga.
Zwróć uwagę na „Sci” - w przypadku nauki, podobnie jak w komputerach, znaczenia kilo, mega, giga itp. Są różne: 1024 (2 ^ 10), 1024 * 1024 (2 ^ 20) itd. 2 megabajty to nie 2 000 000 bajtów .UPDATE Komentator zwrócił uwagę, że istnieją specjalne warunki dla cyfrowych wykładników 2: http://en.wikipedia.org/wiki/Mebibyte
źródło