I’ve been doing some floating-point programming and found that I often need to scale numbers by a power of 2. In other words, to change the exponent.
If I were using integers this would be easy:
let y = x << n
But that doesn’t work for floats.
Instead we have to write something much more verbose:
let y = Double(sign: .plus, exponent: n, significand: x)
Not only is this quite unwieldy, but it is also not obviously correct:
The spelling of that initializer might suggest the exponent of the result would be n
, although by consulting the documentation we see that it will in fact be n + x.exponent
, which is exactly what we want.
(Edit: similarly, it “looks like” the sign of the result would equal the sign
argument value, but in fact that argument acts as a “multiplier”.)
So it works, but it’s neither concise nor completely clear to readers.
• • •
Conceptually, multiplying and dividing by powers of 2 is the same operation on integers as floats.
Thus, to improve the clarity and simplicity of my code, I decided to make floating-point versions of the same shifting operators that integers use.
Their effect is to multiply (<<
) or divide (>>
) the left-hand side by 2 to the power of the right-hand side.
That let me write things like this:
let y = x << n
let z = 1.0 << 256
var w = (a >> (2*i)) + (b << (k+1))
w >>= max(g[j], h[j])
• • •
The implementations for these operators are simple wrappers around the aforementioned initializer.
I put them on BinaryFloatingPoint
(rather than FloatingPoint
) so that they consistently refer to powers-of-2 (instead of some other radix).
And I made them generic over the right-hand-side, like the existing integer versions, so they aren’t restricted to just T.Exponent
.
For myself, these operators greatly improved the readability of my floating-point code, and I expect I’ll include them in many future projects.
So I wanted to gauge what other people think, and whether we should consider adding them to Swift.