Tess
Tess

Reputation: 3

Is there a standard way to define a big list of "magic numbers" or parameters?

Abstractly, say you were building a physics simulation and needed many universal constants or typical values for things like mass. It feels like there should be a standard approach to implementing this? I'm mainly a hobbiest, using C++, and I can think of ways it can be done but unsure what should be done, and I'm worried I'd hit some messy pitfall.

So if you had constants like g, G, pi, alpha, e, h, h-bar etc and lots of values like "Typical Star: Mass = 1 MSolar, wavelength = 600nm" and so on. how would you implement them and potentially group and organise them in a way thats efficient?

I was considering just a header file with the values as either #define macros, or consts, maybe even a std::map, but that feels like adding a lot of global variables in a way that would quickly get out of hand. Is it just something to endure or are there cleaner ways?

Upvotes: 0

Views: 331

Answers (3)

jwezorek
jwezorek

Reputation: 9545

In C++20 many mathematical numeric constants can be included via #include <numbers>. Beyond that in C++, don't use #define, prefer either

constexpr double pi = 3.14159265358979323846;

or

const double pi = 3.14159265358979323846;

The main advantage of using constexpr over const is that constexpr guarantees that the value of the constant is computed at compile time, whereas const only guarantees that the value is not modified at runtime. This means that constexpr constants can be used in contexts where a compile-time constant expression is required, such as in array sizes or template arguments, although typically this kind of usage is more applicable to integer constants.

Upvotes: 0

Aykhan Hagverdili
Aykhan Hagverdili

Reputation: 29985

The C++ way of doing this is to have them as inline constexpr variables in a header file. That's what the standard does with some constants. You can define yours:

namespace Constants {
inline constexpr auto goldenRatio = 1.61803398875;
// ...
};

Upvotes: 1

user17732522
user17732522

Reputation: 76829

Some of these already exist in the standard library and it may be a good idea to follow the approach that the standard library uses to implement more of them.

See https://en.cppreference.com/w/cpp/numeric/constants, for example an implementation for Euler's number looks (slightly simplified) like this in C++20 (in the namespace std::numbers for the standard library, but you should of course use your own):

// variable template for floating point types
template<std::floating_point T> constexpr T e_v = /* value of constant as a literal as precise as possible/neccessary */;

// short-hand for the double case
inline constexpr double e = e_v<double>;

And then one can use std::numbers::e for Euler's number as a double or std::numbers::e_v<float> for Euler's number as a float, and so on.

Upvotes: 0

Related Questions