In my code I have a special type that allows me to switch between 'float' and 'double' for at least some portions of the code.

The problem is constants like '0.015' are default double, and generate tonnes of warnings when I switch to 'float' mode. Because of expressions like 'floatn = 1.5'. However, if I append an 'f' to the end of every constant then I could be removing some of the accuracy benefits of doubles in double mode.

What should I do to get rid of these warnings and still allow me to have the benefit of doubles when I compile it with 'floatn' typedef'd to 'float'?

The vast majority of the warnings come from initialization and simple arithmetic.

Well then it seems highly unlikely you need to worry about loss of precision when converting from float to double, unless your simple arithmetic involves numbers like 23423.4234234098029384233409583405

Incidentally, if you've already defined an alias for the type, there is no need for a further macro for the cast, given C++'s constructor cast syntax:

Well then it seems highly unlikely you need to worry about loss of precision when converting from float to double, unless your simple arithmetic involves numbers like 23423.4234234098029384233409583405

Of course, do note that simple decimal expressions like "0.3" have an infinite number of digits in binary fraction form and will suffer additional rounding if coerced to float.

I used to do stuff like this, but these days I think it's a little bit pointless. What normally happens is that 99.9% of the time you're fine with floats, and then every so often you need to find a bit more precision. Having a blanket float/double type, doesn't really work that well in practice I find. It just means that 'real' will always be a float, and you'll end up using double as and when you need it. That slightly annoying reality, makes a 'real' type a bit superflous imho. Just my 2 cents....

IMO you should be using templates if you need to write code that works with any type. This allows you to use multiple types and change them later without affecting existing code. Besides float and double, it's also possible that you may use one of the integer types, complex, a quaternion type, a vector or matrix type, etc. For example, if you have a generic vector type then you can use vec<unsigned char, 4> or vec_4<unsigned char> to store image data and manipulate it in a convenient manner (although you may also have to implement casts).