Question
I've been told many times that floating point arithmetic has the greatest precision if the numbers operated on are close to 1.0 (or sometimes 0.1). Is there any truth to this?
Clearifications
With "arithmetic" I mean things like a + b, a * b, a / b, but also sqrt(x) and other mathy functions.
To be specific, let's say that all variables are IEEE 64 bit double precision floating point numbers.
Example
In physics simulation code, physical units are usually incorporated by mapping them to floating point values. Here we have a lot of freedom, but one choice is to go with the SI/metric system, something like
# Base units
m = 1.0 # metre
s = 1.0 # second
kg = 1.0 # kilogram
# Derived units
km = 1e+3*m # kilometre
yr = 60*60*24*365.25*s # year
m_sun = 1.98841e+30*kg # mass of the sun
c = 299792458*m/s # speed of light
...
The numerical value of any dimensional variable in such a code depends on the choice of unit system. If we get out a value x == 1.2e-9 and x is meant to be understood as a e.g. a length, we know that this means that x is 1.2 nanometres. Had we chosen to set m = 1e-9, x would instead come out with a value of 1.2, as we are now working in a unit system where the nanometre is the base length unit.
Depending on the physical system studied within the simulation, different "natural" unit systems might be chosen. If our focus is atomic physics, it's probably not ideal to choose the mass of the sun as the base mass unit. Well why not? That's my question. Sure all masses of interest would then have tiny numerical values, but so what? Would the inherent imprecisions of floating point arithmetic somehow be magnified by working with extremely small/large numbers?
I'm aware that a minimum and maximum floating point number exists (something like 1e-324 and 1e+308). Using a unit system so out of wack for the task at hand that the values of our variables go beyond these limits is of course destructive. Keeping values well within those bars though, is there really any difference to whether typical values in the code are of order 1.0, 1e±10, 1e±100?
Note about math functions
Various math functions are in fact noticeable imprecise given very large/small inputs. As an example, cos(1e-8) == 1, i.e. the cos() function cannot distinguish positive numbers smaller than 1e-8. This is not relevant to my question, as the input to cos() must always be a dimensionless, pure number, i.e. independent of the unit system defined in the code. The same goes for all other trigonometric functions, but also exp(), log() and others.