# SE-0368: StaticBigInt

**URL:** <https://forums.swift.org/t/se-0368-staticbigint/59421>\
**Category:** Proposal Reviews\
**Created:** [August 2, 2022, 10:52pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421 "2022-08-02T22:52:21Z")\
**Posts on this page:** 14\
**Page:** 2

<div class="post-metadata">

**Author:** ![benrimmington](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/benrimmington/32/695_2.png) [@benrimmington](https://forums.swift.org/u/benrimmington)\
**Post date:** [August 3, 2022, 11:09pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/21 "2022-08-03T23:09:45Z")

</div>

> [@Nickolas\_Pohilets](#):
>
> Would `BigInt` need additional compiler support to be able to be initialized with a pointer to immortal data in const section? Or `StaticBigInt` provides enough compiler/runtime support to implement `BigInt` in pure Swift code?

The intention is for `StaticBigInt` to support the implementation of `BigInt` in a package. The comparison with `StaticString` exists because `BigInt` could then be moved into the standard library.

* * *

> [@Nickolas\_Pohilets](#):
>
> Is `StaticBigInt` binary compatible with immortal array buffer of words that `BigInt` could use?

No, `StaticBigInt` uses the following ABI-neutral abstraction, to avoid the requirement of contiguously stored words on every platform.

```swift
Builtin.wordAtIndex_IntLiteral(
  _ value: Builtin.IntLiteral,
  _ index: Builtin.Word
) -> Builtin.Word

```

* * *

> [@Nickolas\_Pohilets](#):
>
> Would construction of `BigInt` from `StaticBigInt` require heap allocation and deep copy?

No, a simple implementation could store both a `StaticBigInt` and an array of words (which may be empty if unused).

```swift
public struct BigInt: SignedInteger {
  internal let _constant: StaticBigInt
  internal var _variable: [UInt]
}

```

It's a trade-off between branching on every storage access, and heap allocation on every construction.

Alternatively, [apple/swift-numerics#84](https://github.com/apple/swift-numerics/pull/84) stores a cache of digits for better performance.

```swift
private static let _digits: [BigInt] = (0 ... 36).map {

```

---

<div class="post-metadata">

**Author:** ![benrimmington](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/benrimmington/32/695_2.png) [@benrimmington](https://forums.swift.org/u/benrimmington)\
**Post date:** [August 3, 2022, 11:47pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/22 "2022-08-03T23:47:02Z")

</div>

> [@xwu](#):
>
> Or, we make this subscript non-generic, returning `UInt` only, that being the preferred type anyway. The performance pitfall that can occur with using types of narrower bit width, and the lack of performance benefit (as I understand it) for this more complicated API for types of wider bit width, along with trivial composability, argue against the generic subscript bearing its own weight particularly if it requires these gymnastics to design.

Yes, this is very tempting, as long as we don't give up on the infinite sign extension.

I can rewrite the examples and tests for 64-bit architectures only.

([32-bit testing](https://forums.swift.org/t/32-bit-testing/58640) isn't available on CI bots now, and on my computer the watchsimulator-i386 target displays an empty alert for every executable test.)

---

<div class="post-metadata">

**Author:** ![toph42](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/toph42/32/7807_2.png) [@toph42](https://forums.swift.org/u/toph42)\
**Post date:** [August 4, 2022, 8:47pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/23 "2022-08-04T20:47:40Z")

</div>

> [@benrimmington](#):
>
> > [@allevato](#):
> >
> > Does this operator exist only to provide symmetry with negative literals, as pointed out by the inconsistency in the Future Directions section?
> 
> Yes, and it's implemented as `@_alwaysEmitIntoClient`, in case we can remove it later.

I don’t get it. What’s the downside to not including it in the first place?

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [August 4, 2022, 8:53pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/24 "2022-08-04T20:53:48Z")

</div>

> [@toph42](#):
>
> I don’t get it. What’s the downside to not including it in the first place?

Swift supports explicitly writing out a positive sign in front of an integer literal. This support is provided in the form of `prefix +` defined in the standard library for all types expressible by an integer literal. Excluding the function in question for `StaticBigInt` would drop that support, but only for integer literals that are used to express large integers. This would be a mystifying inconsistency that's bad for the end user experience.

---

<div class="post-metadata">

**Author:** ![benrimmington](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/benrimmington/32/695_2.png) [@benrimmington](https://forums.swift.org/u/benrimmington)\
**Post date:** [August 10, 2022, 8:47am UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/25 "2022-08-10T08:47:14Z")

</div>

I've created a pull request that uses _only_ a "non-generic" subscript, in case the Language Workgroup decides to amend the proposal.

```swift
/// Returns a 32-bit or 64-bit word of this value's binary representation.
///
/// The words are ordered from least significant to most significant, with
/// an infinite sign extension. Negative values are in two's complement.
///
/// let negative: StaticBigInt = -0x0011223344556677_8899AABBCCDDEEFF
/// negative.signum() //-> -1
/// negative.bitWidth //-> 118
/// negative[0] //-> 0x7766554433221101
/// negative[1] //-> 0xFFEEDDCCBBAA9988
/// negative[2] //-> 0xFFFFFFFFFFFFFFFF
///
/// let positive: StaticBigInt = +0x0011223344556677_8899AABBCCDDEEFF
/// positive.signum() //-> +1
/// positive.bitWidth //-> 118
/// positive[0] //-> 0x8899AABBCCDDEEFF
/// positive[1] //-> 0x0011223344556677
/// positive[2] //-> 0x0000000000000000
///
/// - Parameter wordIndex: A nonnegative zero-based offset.
public subscript(_ wordIndex: Int) -> UInt { get }

```

* * *

For expressions like `StaticBigInt(+42)` and `UInt64(+0xFFFF_FFFF_FFFF_FFFF)`, another alternative to waiting for a "plus sign" in the language is:

```swift
extension ExpressibleByIntegerLiteral {

  /// Creates a new instance from the given integer.
  ///
  /// If the value passed as `source` is not representable in this type, a
  /// runtime error may occur.
  ///
  /// - Parameter source: An immutable arbitrary-precision signed integer.
  public init(_ source: StaticBigInt) {
    let target = IntegerLiteralType(_builtinIntegerLiteral: source._value)
    self.init(integerLiteral: target)
  }
}

```

It was originally suggested as `init(dynamicIntegerLiteral:)` by @John_McCall. However, it's blocked by an issue where overflow can result in a zero-initialized value (without a compile-time or run-time error). I don't know how to fix that issue, and I didn't want to delay this proposal. I'm also unsure of the effect on source compatibility, if it's implemented without an argument label.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [August 10, 2022, 8:36pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/26 "2022-08-10T20:36:00Z")

</div>

As I understand it, there is a general bug where we don't emit runtime diagnostics during generic initialization of integer literals. That is something we need to fix, but I don't think it's reasonable to block this on that.

---

<div class="post-metadata">

**Author:** ![glessard](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/glessard/32/409_2.png) [@glessard](https://forums.swift.org/u/glessard)\
**Post date:** [August 10, 2022, 10:16pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/27 "2022-08-10T22:16:45Z")

</div>

This is a very useful addition which will add great flexibility. I like the idea of unblocking literals for external big int implementations without otherwise committing the language.

The latest version with a non-generic subscript is a good improvement. Simplicity wins.

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [August 18, 2022, 9:56pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/28 "2022-08-18T21:56:02Z")

</div>

Hello Everyone,

The discussion of the generic subscript in this thread led to a proposed change to make that subscript non-generic. The author has [amended the proposal](https://github.com/apple/swift-evolution/pull/1736) with that change. The Language Workgroup is extending the review until next Tuesday to provide more time to discuss the amended proposal.

Thanks everyone,  
Doug

---

<div class="post-metadata">

**Author:** ![Mordil](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mordil/32/5840_2.png) [@Mordil](https://forums.swift.org/u/Mordil)\
**Post date:** [August 22, 2022, 5:35pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/29 "2022-08-22T17:35:48Z")

</div>

Why are we proposing a `StaticBigInt` if we think an eventual `BigInt` will just "deprecate" it much like `StaticString` & `String`, if we could instead just jump to the `BigInt` addition?

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [August 22, 2022, 5:52pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/30 "2022-08-22T17:52:07Z")

</div>

`BigInt` would not deprecate `StaticBigInt`. `StaticBigInt` is a tool for expressing arbitrary-precision integer literals, which can be useful for negotiating the boundary between the language syntax and the static/dynamic semantics of a specific type, which needn't be arbitrary-precision to benefit from the existence of `StaticBigInt`.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [August 22, 2022, 6:10pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/31 "2022-08-22T18:10:46Z")

</div>

> [@John\_McCall](#):
>
> `BigInt` would not deprecate `StaticBigInt`. `StaticBigInt` is a tool for expressing arbitrary-precision integer literals, which can be useful for negotiating the boundary between the language syntax and the static/dynamic semantics of a specific type, which needn't be arbitrary-precision to benefit from the existence of `StaticBigInt`.

In addition, an eventual `BigInt` might not be in the standard library, but `StaticBigInt` has to be in order to provide this function for literals.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [August 22, 2022, 7:25pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/32 "2022-08-22T19:25:43Z")

</div>

I almost forgot to review this. This has a +1 for me. Arbitrary length integer literals is a definite improvement over the status quo.

I realize it's not really up for discussion yet, but I absolutely support the future direction of moving the prefix `+` for positive numbers to the grammar instead of having it be an operator. I have never once used the prefix `+` operator on anything other than a literal.

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [August 29, 2022, 10:42pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/33 "2022-08-29T22:42:24Z")

</div>

This proposal has been [accepted](https://forums.swift.org/t/accepted-se-0368-staticbigint/59962), thank you everyone!

Doug

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [August 29, 2022, 10:42pm UTC](https://forums.swift.org/t/se-0368-staticbigint/59421/34 "2022-08-29T22:42:34Z")

</div>

Closed on August 29, 2022, 10:42pm UTC



[Previous page](https://forums.swift.org/t/se-0368-staticbigint/59421.md?page=1)
