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

New pow function #10

Merged
merged 5 commits into from
Dec 28, 2017
Merged

New pow function #10

merged 5 commits into from
Dec 28, 2017

Conversation

abelmarm
Copy link
Contributor

@abelmarm abelmarm commented Dec 24, 2017

pow(my_big_int, x) has been added along with a change to the name of the function abs -> big_abs to avoid conflict with cmath.

relates to #5

@abelmarm
Copy link
Contributor Author

I just fall in that the pow function will have the same problem as the abs function, it could be renamed or made static.

@faheel
Copy link
Owner

faheel commented Dec 24, 2017

You're right, there will be conflicts if we simply have pow, sqrt etc. I think we should make all the math functions static, as that's the standard way.

UPDATE: I just tested it after including the released file, cmath and even cstdlib. No warnings or errors.

---
Returns the absolute value of a BigInt.
*/

BigInt abs(const BigInt& num) {
const BigInt big_abs(const BigInt& num) {
Copy link
Owner

Choose a reason for hiding this comment

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

Why return a const BigInt and not a BigInt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To be honest, I was just trying things to resolve a problem.

Return a BigInt equal to my_big_int^x
NOTE: x could be BigInt, long long, or string
*/
BigInt pow(BigInt my_big_int, const BigInt x) {
Copy link
Owner

@faheel faheel Dec 24, 2017

Choose a reason for hiding this comment

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

  • I made a mistake while mentioning the parameters for pow (sorry!). I've updated them now. It should be
    (const T& base, const long long& exponent)
    where the type T is BigInt, long long and std::string.
  • The exponent should only be an integer (long long), as I can't seem to think of situations where a BigInt would need to be raised to an exponent greater than 263-1 (it would require > 86 EiB of RAM!).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, on it

@abelmarm
Copy link
Contributor Author

Hmmmm. about the cmath library, maybe I goofed somewhere, but wouldn't it still be better if they were member functions, that way an user can use them without the need to additionally add the respective library and it would be easier to know about them without reading all the doc.

@faheel
Copy link
Owner

faheel commented Dec 25, 2017

  • All the user needs to do is #include "BigInt.hpp" (the released file), irrespective of whether the math functions are member functions or not.

  • If they were member functions, you wouldn't be able to write:

    BigInt big_num = pow("123", 12345);

    This can be helpful as there's no need to first create a temporary and then call pow on it:

    BigInt big_temp = 123;
    BigInt big_num = big_temp.pow(12345);

    Similarly for gcd and lcm.

@abelmarm
Copy link
Contributor Author

abelmarm commented Dec 25, 2017

I have changed the pow function to match the new requirements, but including:

#include "operators/relational.hpp"
#include "operators/unary_arithmetic.hpp"

Gives me an error when compiling.

@faheel
Copy link
Owner

faheel commented Dec 25, 2017

What is the error that you get?

Copy link
Owner

@faheel faheel left a comment

Choose a reason for hiding this comment

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

All non-integral parameters (including integers greater than int) should be passed as constant references (const Type&).

Return a BigInt equal to my_big_int^x
NOTE: x could be BigInt, long long, or string
*/
BigInt pow(BigInt my_big_int, long long x) {
Copy link
Owner

Choose a reason for hiding this comment

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

The parameters should be passed as constant references (const Type&).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

TEST_CASE("abs", "[conversion][string]") {
BigInt a("-12");
BigInt b("32");
BigInt c("-50");
Copy link
Owner

Choose a reason for hiding this comment

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

This file should be test/functions/math.test.cpp. It already exists. You can add just the test cases for pow().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright.

@abelmarm
Copy link
Contributor Author

Ok, I think I found the problem, when testing the pow function I get this error:

Creating binary: bin/functions/math.test ... build/functions/math.test.o: In function `pow(BigInt const&, long long const&)':
math.test.cpp:(.text+0x1dd2): undefined reference to `BigInt::operator/(BigInt const&) const'
math.test.cpp:(.text+0x1f21): undefined reference to `BigInt::operator%(long long const&) const'
math.test.cpp:(.text+0x1f68): undefined reference to `BigInt::operator*=(BigInt const&)'
math.test.cpp:(.text+0x1f8c): undefined reference to `BigInt::operator/=(long long const&)'
math.test.cpp:(.text+0x1faa): undefined reference to `BigInt::operator*=(BigInt const&)'
math.test.cpp:(.text+0x1fc3): undefined reference to `BigInt::operator*=(BigInt const&)'
math.test.cpp:(.text+0x1ff6): undefined reference to `BigInt::operator-(long long const&) const'
math.test.cpp:(.text+0x2010): undefined reference to `BigInt::operator/(long long const&) const'
math.test.cpp:(.text+0x2063): undefined reference to `BigInt::operator*(BigInt const&) const'

Which is because I have not added the library binary_arithmetic.hpp in the math.hpp file, the problem is that when I add this library I get this other error in return when compiling:

Compiling object: build/functions/math.test.o ... In file included from include/functions/math.hpp:14:0,
                 from test/functions/math.test.cpp:7:
include/operators/binary_arithmetic.hpp: In member function ‘BigInt BigInt::operator-(const BigInt&) const’:
include/operators/binary_arithmetic.hpp:92:18: error: cannot convert ‘const BigInt’ to ‘int’ for argument ‘1’ to ‘int abs(int)’
     if (abs(*this) > abs(num)) {
                  ^
include/operators/binary_arithmetic.hpp:92:29: error: cannot convert ‘const BigInt’ to ‘int’ for argument ‘1’ to ‘int abs(int)’
     if (abs(*this) > abs(num)) {
                             ^
.
.
.

@faheel
Copy link
Owner

faheel commented Dec 26, 2017

@abelmarm Have you been able to fix the issue you were facing? If not, please push your changes so that I can take a look and help.

@abelmarm
Copy link
Contributor Author

I haven't, I have pushed the changes

Copy link
Owner

@faheel faheel left a comment

Choose a reason for hiding this comment

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

These changes fix the problem

@@ -6,6 +6,8 @@
#include "functions/conversion.hpp"
#include "functions/math.hpp"
#include "operators/io_stream.hpp"
#include "operators/relational.hpp"
#include "operators/unary_arithmetic.hpp"
Copy link
Owner

Choose a reason for hiding this comment

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

Add:

#include "operators/binary_arithmetic.hpp"

Copy link
Owner

Choose a reason for hiding this comment

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

conversion.hpp and unary_arithmetic.hpp are not needed here.


#include "operators/relational.hpp"
#include "operators/unary_arithmetic.hpp"

#include "operators/binary_arithmetic.hpp"
Copy link
Owner

Choose a reason for hiding this comment

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

Remove all operator/ includes.

Copy link
Owner

@faheel faheel left a comment

Choose a reason for hiding this comment

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

  • Try different values in different test cases.

@@ -6,6 +6,8 @@
#include "functions/conversion.hpp"
#include "functions/math.hpp"
#include "operators/io_stream.hpp"
#include "operators/relational.hpp"
#include "operators/unary_arithmetic.hpp"
Copy link
Owner

Choose a reason for hiding this comment

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

conversion.hpp and unary_arithmetic.hpp are not needed here.


long long a1 = 12;
long long b1 = 32;
long long d1 = 23;
Copy link
Owner

Choose a reason for hiding this comment

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

Directly pass these values to the function if they're not to be reused.

TEST_CASE("Pow with BigInt", "[conversion][string]") {
BigInt a("12");
BigInt b("32");
BigInt c("50");
Copy link
Owner

Choose a reason for hiding this comment

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

Just one BigInt object is enough. You can reassign it values as required:

BigInt big_num = 12;

...

big_num = 32;

Also, its better to check for values of different orders of magnitude. Eg. 2 digit, 8 digit, 20 digit, 100 digit. You can use WolframAlpha or Python to easily generate numbers of a certain size.


REQUIRE(pow(a, b1).to_string() == "34182189187166852111368841966125056");
REQUIRE(pow(b, a1).to_string() == "1152921504606846976");
REQUIRE(pow(c, d1).to_string() == "1192092895507812500000000000000000000000");
Copy link
Owner

Choose a reason for hiding this comment

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

No need of .to_string(). Simply do:

REQUIRE(pow(big_num, 12) == "34182189187166852111368841966125056");

@abelmarm
Copy link
Contributor Author

Changes done, don't mind the sqrt merge I was working on that when i did what you said.

a = 32;
REQUIRE(pow(a, (long long)12) == "1152921504606846976");
a = 50;
REQUIRE(pow(a, (long long)23) == "1192092895507812500000000000000000000000");
Copy link
Owner

Choose a reason for hiding this comment

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

No need to explicitly cast to long long.

REQUIRE(pow("33", (long long)27) == "99971538734896047460249499950752967950177");
REQUIRE(pow("21", (long long)59) == "1025506433613486607375777617584133309366191904729927960524981845743709132117581");
REQUIRE(pow("42", (long long)59) == "591164210212831306083214062268562882225191490961799646040575789354982868342002274605481253142528");
REQUIRE(pow("50", (long long)51) == "444089209850062616169452667236328125000000000000000000000000000000000000000000000000000");
Copy link
Owner

Choose a reason for hiding this comment

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

No need to explicitly cast to long long.

REQUIRE(pow((long long)20, (long long)40) == "10995116277760000000000000000000000000000000000000000");
REQUIRE(pow((long long)30, (long long)45) == "2954312706550833698643000000000000000000000000000000000000000000000");
REQUIRE(pow((long long)45, (long long)30) == "39479842665806602234295041487552225589752197265625");
REQUIRE(pow((long long)40, (long long)20) == "109951162777600000000000000000000");
Copy link
Owner

Choose a reason for hiding this comment

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

No need to explicitly cast to long long.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't compile otherwise.

Copy link
Owner

Choose a reason for hiding this comment

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

I think only pow(long long, long long) causes problems. Try casting just the base as long long if that's the case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The workaround would be to write ll at the end.

Copy link
Owner

Choose a reason for hiding this comment

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

Use uppercase LL though since its easier to differentiate from 11.

@faheel
Copy link
Owner

faheel commented Dec 27, 2017

Once the changes are done please squash the commits into a single commit. Then it'll be good to merge 👍

@abelmarm
Copy link
Contributor Author

Everything is done and committed to a final commit.

@faheel
Copy link
Owner

faheel commented Dec 27, 2017

I see, but the commits haven't been squashed into a single commit. Try the following:

  1. git rebase -i HEAD~17
  2. Change the action frompick to squash for all commits except the first one and save.
  3. git push -f

@abelmarm abelmarm force-pushed the master branch 3 times, most recently from 4b4348e to c3fe8b7 Compare December 27, 2017 18:15
@abelmarm
Copy link
Contributor Author

abelmarm commented Dec 27, 2017

I had a lot of problems doing that, but I think it kinda worked at last, the conflicting files are the README because you worked on it after my last fetch, but I just hard copied it, and both math files which had the problematic includes we had talked about before.

@faheel faheel merged commit 90b17c6 into faheel:master Dec 28, 2017
@faheel
Copy link
Owner

faheel commented Dec 28, 2017

Thanks a lot for contributing @abelmarm!

@faheel
Copy link
Owner

faheel commented Dec 28, 2017

I overlooked a few things (sorry about that!). Fixed them in the commits 0031c0a and 4d0b71b.

@faheel faheel added the functions: math Math functions label Dec 29, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
functions: math Math functions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants