Can we move _significandMask to FloatingPoint.swift?

The standard library file FloatingPointTypes.swift.gyb has the declaration _significandMask for concrete types:

extension ${Self}: BinaryFloatingPoint {
  @inlinable // FIXME(inline-always) was usableFromInline
  internal static var _significandMask: ${RawSignificand} {
    @inline(__always) get {
      return 1 &<< ${RawSignificand}(significandBitCount) - 1
    }
  }
}

I would like to move that property into the FloatingPoint.swift file, constrained by RawSignificand: FixedWidthInteger (alongside the _convert and random methods):

extension BinaryFloatingPoint where RawSignificand: FixedWidthInteger {
  @inlinable
  internal static var _significandMask: RawSignificand {
    return (1 << significandBitCount) &- 1
  }
}

There is already one place in FloatingPoint.swift where this could be used right away:

let significandMask = ((1 as RawSignificand) << Self.significandBitCount) &- 1

And my work to improve random(in:using:) will benefit from it as well.

Is this an acceptable change? Should anything be different about the declaration? Maybe @_transparent?

I will note that there is one minor difference in the implementations: the existing version uses &<< because the concrete types all have more bits in RawSignificand than are used by significandBitCount. However an arbitrary third-party type might use all the bits in the type for its significand, so the replacement uses <<.

For the same reason, the replacement uses &-, because if all the bits are used for the significand, the result should have all bits set to 1.

I wasn’t sure where to ask about this, hopefully I’m in the right place. If this change is acceptable, I’d be happy to raise a pull request for it.

1 Like

I'm a little reluctant to expose this in the way you suggest because there are some very strange FP formats for which it might not make sense. So far, we only support IEEE754 formats and Float80. But I'm not sure if a significand mask really makes sense for something like PPC quad-precision format. Certainly the significand mask for that format cannot be simply derived from the significand bit count. (Admittedly, Swift might never support that particular format, but if it did, I presume it would need to conform to BinaryFloatingPoint.)

Of course, @scanon is much more of an expert than I am.

You can't remove any existing ABI-public declarations (which @inlinable internal qualifies as), because someone might be referencing them as is. If you want to add a new declaration, go ahead (with no comments on how to annotate it), but the existing ones have to stay.

2 Likes

This isn't a problem, because FloatingPoint implies an IEEE 754 format. What @jrose said is absolutely correct, however.

1 Like