Skip to content

Fix asInt conversion and test across Int8-128 & UInt8-UInt128#12

Open
kdubb wants to merge 1 commit into
mgriebling:mainfrom
kdubb:fix/asInt
Open

Fix asInt conversion and test across Int8-128 & UInt8-UInt128#12
kdubb wants to merge 1 commit into
mgriebling:mainfrom
kdubb:fix/asInt

Conversation

@kdubb

@kdubb kdubb commented Apr 7, 2025

Copy link
Copy Markdown

The current implementation of asInt<I:FixedWidthInteger>() is currently broken. Amongst other issues, it fails to convert BigDecimal(0) and BigDecimal(1).

I fixed the implementation by:

  1. Fixing the check for fractions
    It now uses a rounded (via truncation) value and then uses a simple truncated != self comparison to reject fractions.
  2. Added a asFixedWidthInteger() extension function to BInt
    Uses BInt.asMagnitudeBytes() and sign conversion to build an integer of the appropriate size.

BInt.asInt vs asFixedWidthInteger()

Adding the asFixedWidthInteger() is necessary because BInt only supports asInt() -> Int (non-generic and native size only). Obviously this causes issues with integer types that have a range that differs from Int.

asFixedWidthInteger() instead uses BInt.asMagnitudeBytes() to export the bytes and copies them to an integer of the appropriate size, after which it modifies the sign as appropriate. Ultimately this, or a similar generic function, should probably be transferred to the BInt package.

With the conversion from BInt to any FixedWidthInteger encapsulated in an extension function, and because I'm using asMagnitudeBytes() to do the byte export from BInt, I was able to reduce the # of operations to a single withExponent(0, .towardZero) plus the range checks.

Warning

An issue with conversion from Swift's Int128 to BigDecimal was discovered, which is fixed in #11. Until that PR is merged, some of the Int128 tests will fail.

Note

I used Swift Testing for the test suite for its native support of parameterized tests which made testing and debugging much easier.

To workaround BInt only supporting `asInt() -> Int` (none generic and native size only). I created `asFixedWidthInteger()` in `Extensions.swift`. This functions grabs the bytes for the BInt and copies them into an integer of the appropriate size with appropriate sign conversions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant