There are some inconsistencies in the constants in Float
. There is f32::PI_2
, Float::two_pi
, and Float::frac_pi_2
. I find it hard to come up with consistent names for all the constants, but there may be a better solution: why have all those fractions at all? frac_pi_2
is only one character shorter than (pi / 2.0)
. (pi * 2.0)
is four characters more than two_pi
, but you don’t always need the parentheses. I propose that the following constants be removed from Float
:
sqrt2
frac_1_sqrt2
two_pi
frac_pi_2
frac_pi_3
frac_pi_4
frac_pi_6
frac_pi_8
frac_1_pi
frac_2_pi
frac_2_sqrtpi
log2_e
log10_e
ln_2
ln_10
The only math constants to keep are pi
and e
.
For multiples and fractions, it should not matter from a performance point of view due to constant folding, right? If we keep e.g. two_pi
, people will write pi * 2.0
anyway, which leads to inconsistencies. (I did a search on GitHub, and I indeed found cases like this. It might have been pi * 0.5
instead of the fraction.)
I conducted a GitHub search a few weeks ago, with the following results:
-
frac_pi_2
is used in 16 places, excluding the Rust project and wrappers. -
frac_pi_6
is not used, except in wrappers. -
frac_2_sqrtpi
is not used, except in wrappers. -
pi
has 1985 search results. I did not count how many were wrappers, but for the other constants that was around 35, so there probably are more than 1900 places where pi is used.
For the precomputed function values, these can be computed manually with little effort. There is a runtime cost involved here (please correct me if I am wrong, I do not know much about the compiler internals), but you can do the pre-computation manually, or you can put the constant in your own code if you really need a constant. If we do allow precomputed function values, then the decision which ones to include is arbitrary. sqrt2
is common, but why not sqrt3
and sqrt5
then? I think that in a situation where you need a very specific constant, you are likely to need other constants (not in Float
) as well, so you’d need to define the missing ones anyway.
When I searched Rust files on GitHub for sqrt2
, I found seven results that were not wrappers:
return 0.5 * (1.0 + unsafe { erf(x / Float::sqrt2()) });
-
let sqrt2 = 2.0f32.sqrt();
,out[sh_index(l, m)] = sqrt2 * x * y * z;
-
let sqrt2: T = Float::sqrt2();
,(x / sqrt2, z / sqrt2)
-
z *= 1f64 / SQRT2;
(uses the constant fromf64
) -
let p1 = Particle {m: 5., pos: Vector2{x: -SQRT2/0.2, y: -SQRT2/0.2} };
(uses the constant fromf64
) -
v.xyz[ix] *= SQRT2;
(uses the constant fromf32
) let sqrt2 = (2.0 as f32).sqrt();
People compute or define it manually anyway, and division by sqrt2
is used instead of multiplication by frac_1_sqrt2
. I found one use of sqrt3
(which had to be defined manually).
Conclusion: removing exotic constants would allow the names of the remaining constants to be consistent. Many constants appear to be (virtually) unused, and if you do need them, defining them manually is no big deal.