2013-02-28 9 views
9

więc często widzę coś takiego:tym operacje arytmetyczne przy definiowaniu stałej

#define gf_PI f32(3.14159265358979323846264338327950288419716939937510) 
#define gf_PIhalf f32(3.14159265358979323846264338327950288419716939937510 * 0.5) 

oznacza to, że połowa wartości PI jest obliczany za każdym razem używam gf_PIhalf w moim kodu, prawda?
Czy nie lepiej byłoby zamiast tego dosłownie wpisać wartość połowy PI?

nie byłoby nawet lepiej, aby wykonać następujące czynności:

#define gf_PI f32(3.14159265358979323846264338327950288419716939937510) 
const float gf_PIHalf = gf_PI * 0.5f; // PIHalf is calculated once 

Wreszcie czy nie byłoby najlepiej zrobić to w ten sposób (i dlaczego nie wydaje się być powszechną praktyką):

const float gf_PI = 3.14159265358979323846264338327950288419716939937510; 
const float gf_PIHalf = gf_PI * 0.5f; 
+1

Czy naprawdę dbasz o to, czy twój program wykonuje więcej mnożenia? czy to naprawdę jest tak ważne? – Smash

+0

To jest świetne pytanie. Kiedyś zadałem podobne pytanie dotyczące ograniczeń pamięci i wydajności, i myślę, że standardowa odpowiedź, którą otrzymałem, była podobna do "Szczerze mówiąc, w takim tempie, to nie ma znaczenia, to tak mała ilość danych, że stosunek wydajności nie". t dużo trafienia. " Myślę, że w tym przypadku, Przekonasz się, że wydajność programu niekoniecznie cierpi VS. pomysł, że otrzymujesz ponowną kalkulację, za którą możesz zaufać za każdym razem. Jeśli masz pewność co do arytmetyki, wybrałbym czystą wydajność. – plast1K

+0

Zobacz, dobry kompilator optymalizuje z dala [nawet kompletny bałagan w ten sposób] (http://stackoverflow.com/questions/15114140/writing-binary-number-system-in-c-code/15114188#15114188) w jedną stałą ... –

Odpowiedz

11

oznacza to, że połowa wartości PI jest obliczany za każdym razem używam gf_PIhalf w moim kodu, prawda?

Nie, mało prawdopodobne.

Można racjonalnie liczyć na kompilator, aby wykonać to mnożenie w czasie kompilacji, a nie w czasie wykonywania.

3

Twoje wnioski są nieco poprawne, z tym wyjątkiem, że wersja #define prawie definitywnie rozwiązuje się w czasie kompilacji, a bit o typach stałych jest nietypową praktyką. Są powszechną praktyką we współczesnym dobrym kodzie. #define s są już martwe do tego użytku. najlepiej praktyka jest zdefiniowanie globalnych, zakres plików w przestrzeni nazw bezimiennego:

namespace 
{ 
    const float g_SomeGlobal = 123.456f; 
} 

Zapobiega to ktoś spoza jednostki tłumaczeniowej od bycia w stanie „zobaczyć” g_SomeGlobal.