Closed dlesnoff closed 1 year ago
The only workaround yet is to use the keyword
cast[int]
. But this does not always do what we want.
That never does what you want. I suggest you read the documentation for cast
, it merely reinterprets the underlying bits.
I generally agree that functions to convert a BigInt
to some integer types are useful, but how should we handle the case of the BigInt
being out of range? I see several possibilities:
Option
Inf
/-Inf
)x mod 2^n
where n
is the number of bits of the resut)EDIT: Added a 4th option.
@Araq: you might be interested in this discussion, i.e. give your opinion on how to best proceed with this.
We can not return the lowest/highest value for type conversions to integers as a BigInt can be any value that an int can contain.
The first solution forces the user to wrap any potentially dangerous cast in a try .. except .. finally
clause.
I have not used Option
in my programs yet, if I understand the user will have to check (everytime ?) whether the Option contains a value ?
IMO the prototype should be:
proc toFixedInt*[T](b: BigInt): Option[T]
with the hopefully obvious semantics.
This issue should be reopened, toSignedInt
only provides conversion to signed integers. I'd also argue that it should be renamed to toInt
and also support unsigned integers (rather than adding a new toUnsignedInt
function).
I also really need pred
and succ
. Implementation can be as simple as:
proc pred*(a: BigInt; def = 1): BigInt =
a - initBigInt(def)
proc succ*(a: BigInt; def = 1): BigInt =
a + initBigInt(def)
This has been addressed in https://github.com/nim-lang/bigints/pull/100.
Since BigInt's limb parameter has become private, thus we can not easily cast BigInts with absolute value less than
2^32
to anint
or even auint32
. The only workaround yet is to use the keywordcast[int]
. But this does not always do what we want. To get only the smallest limb, we also have to define a mask like2^32 - 1
and to apply an ineffectiveand
. Can we implement some functions like … ?:toUint32(a: BigInt): uint32
returns the only limb for BigInts between 1-2^32 and +2^32-1 (small BigInts).toInt(a: BigInt): int
cast the BigInt if it is small enough, into an int, according to the sign of BigInt, with correct representation (2's complement) and raises a ValueError if the cast can not be done (if int is stored on 32 bits, it may not fit if the heavy weight bit of the uint32 corresponding to first limb is 1).toUint64(a: BigInt): uint64
returns the uint64 made up of one to two limbs, if the BigInt is small enough.toFloat
like described in the similar issue #34.