Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fastLog2 operation, closes #67 #71

Merged
merged 10 commits into from
Jan 31, 2022
Merged

Conversation

dlesnoff
Copy link
Contributor

@dlesnoff dlesnoff commented Jan 9, 2022

Add a bitops-like operation for BigInts with respective test.
Solves #67.

src/bigints.nim Outdated
@@ -959,3 +959,5 @@ iterator `..<`*(a, b: BigInt): BigInt =
while res < b:
yield res
inc res

func fastLog2*(a: BigInt): int = bitops.fastLog2(a.limbs[a.limbs.high]) + 32*(a.limbs.len-1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Put the body of the proc in a separate line, and add doc comment.

@narimiran
Copy link
Member

Ok, maybe the implementation is fast, but should that be reflected in the name of the function? Why not just log2?

@dlesnoff
Copy link
Contributor Author

dlesnoff commented Jan 10, 2022

Ok, maybe the implementation is fast, but should that be reflected in the name of the function? Why not just log2?

@narimiran I do not want to say that my implementation is fast, but I want the user to understand this is the equivalent for BigInt of the fastLog2 function of the std/bitops library (that usually takes as input a type from the type group SomeInteger).

@konsumlamm
Copy link
Contributor

Hmm, I wonder what would be best for negative numbers. I think calculating log2 of the absolute value makes sense, but then it should at least be documented. Alternatively, we could throw an exception, but I don't know how useful that would be.

@dlesnoff dlesnoff changed the title Add fastLog2 operation Add fastLog2 operation, closes #67 Jan 13, 2022
Specified edge case

Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
src/bigints.nim Outdated
## If `a` is zero, returns -1.
if a.isZero:
return -1
bitops.fastLog2(a.limbs[a.limbs.high]) + 32*(a.limbs.len-1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a.limbs.high and a.limbs.len-1 are the same thing. Why use both, and not just one of those variants?

@@ -385,6 +385,20 @@ proc main() =
doAssert "fedcba9876543210".initBigInt(base = 16) == b
doAssert "ftn5qj1r58cgg".initBigInt(base = 32) == b

block: # fastLog2
let a = one shl 31
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need some "not-power-of-two" tests too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any idea of easily checkable tests then ?
I have tested the fastLog of a+b which is not a power of 2.
I have added one test but it is not obvious what is it’s logarithm.
There are not much possible errors with this simple function and I am tired of waiting 30 seconds every time I have to test my code. It is much longer now with all the GC’s.
Maybe some factorial, since with Stirling approximation, we can guess the number of digits ahead ?

Copy link
Contributor

@konsumlamm konsumlamm Jan 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also test values with all 1's, e.g. one shl 64 n- 1 and a few negative non-powers-of-two.

As for running the tests yourself, you can just nim r tests/tbigints.nim. (In theory, the behavior should be the same for all GCs, but in practice, there are bugs, as exemplified by #88.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any idea of easily checkable tests then ?

I would do some sanity checks, e.g. log of 7, 8, 9, 24, 32, 48, etc., just to make sure it works for the basics. And then do what @konsumlamm suggests.

@dlesnoff
Copy link
Contributor Author

dlesnoff commented Jan 30, 2022

Are the new tests sufficient ?

@konsumlamm
Copy link
Contributor

Are the new tests sufficient ?

Have you read #71 (comment) and #71 (comment)?

@dlesnoff
Copy link
Contributor Author

I have, I added tests corresponding to these comments and I am asking if the new tests are okay for you.

@konsumlamm
Copy link
Contributor

Huh, for some reason your latest commit doesn't shop up here... Maybe you can try to rebase/merge the master branch.

@dlesnoff
Copy link
Contributor Author

dlesnoff commented Jan 31, 2022

I was some commits behind master. That might be the cause.
Commit did show up in the history though (but not in diff), so I was quite surprised by your answer.
The diff is now correct.

@narimiran narimiran merged commit 88dfbd9 into nim-lang:master Jan 31, 2022
@dlesnoff dlesnoff deleted the fastLog2 branch February 16, 2022 21:49
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.

None yet

3 participants