Combine integral and fraction part macros into a new macro or a double at compiletime

Viewed 129

I have a major and a minor version number available in two preprocessor defines

#define i 123
#define f 4567

and need to provide a function which returns them combined as a double value where the major number is the integral and the minor number the fractional part.

Besides just repeating those numbers, all solutions i could come up with are quite expressive; see for example here: https://godbolt.org/z/rg3GyR

Without constexpr it would get even more expressive but could be done as well.

In MS world, i got away with

  #define me i.f
  double df() { return me; }

but Standard C++ doesn't offer that possibility.

I'm wondering if there exists a simple standard conformant way to do that.

1 Answers

@NathanOliver's comment about precision in storing things as a double is an important one. However, if you would like to proceed by storing things as an explicit double, you can use the token-pasting operator and some levels of macro indirection to explicitly glue everything together:

#define MAJOR 123
#define MINOR 4567

/* Two macro levels are necessary here so that the arguments MAJOR
 * and MINOR get expanded out to their true values.
 */
#define GLUE2(a, b) a##.##b
#define GLUE(a, b) GLUE2(a, b)

/* Now, VERSION is the constant 123.4567. Or at least, the closest
 * approximation of that value using a double.
 */
#define VERSION GLUE(MAJOR, MINOR)

Other options that might work better for you:

  1. Create an struct to represent your version, and have it explicitly store a major and minor version field. This the most "honest" way of encoding your idea.

  2. Pack the version into an unsigned integer (perhaps 32-bit or 64-bit) where the upper half of the integer is the major version and the lower half is the minor version. This allows you to compare versions using straight integer operations, but also allows you to do Silly Things like multiplying versions, modding by versions, etc.

  3. Use strings for everything. This lets you store versions of any length and any level of description.

Related