I'm on my phone, can respond to problem later, but I think I instead what you want now.
As for the assignment operator =, remember that it is one of the few operators that is right associative.
Permutation: Permutation - Wikipedia, the free encyclopedia
They are like combinations, but in math combinations don't take in to account order. So your outfit is a combination of cloths, and your meal is a combination of foods, but a book is a permutation of words (as the order of the words maters, were as the order of your clothes has no meaning.)
Wait, so all you want is a map from:
0 |-> "0000"
1 |-> "0001"
...
10 |-> "1010"
11 |-> "1011"
12 |-> "1100"
...?
But for any base. Like normal arithmetic?
If by a map you mean listing all possible combinations of RC given the number base, yes. But without iterating each combination that is required to get to RC.
Picture this: RC = 3, NB = 2.
0
1
10 < this is the combinaion RC wants.
A "map" is just another name for a function.
What I ment was... ( Question: ) You want a function, say f, such that:
Code:NB = 2; f(0) == "0" f(1) == "1" f(2) == "10" f(3) == "11" ... //assuming string comparisons, and not pointer comparisons
N.h:N-test.cpp:Code:#ifndef N_H #define N_H #include <cmath> #include <iostream> #include <string> #include <vector> //N for Natural number class N { private: static unsigned int radix; public: static std::vector<char> digits; unsigned long long n; //the internal representation of this N object //default constructor N() : n(0) {} //other constructor(s) N(unsigned long long k) : n(k) {} //copy constructor N(const N &num) : n(num.n) {} //destructor virtual ~N() {} //assignment operator(s) virtual const N& operator=(const N &num) { n = num.n; return *this; } virtual const N& operator=(unsigned long long k) { n = k; return *this; } //casting operators virtual operator unsigned long long() const { return n; } virtual operator std::string() const { return toString(); } //static accessor(s) static unsigned int getRadix() { return radix; } //static mutator(s) static void setRadix(unsigned int r) { if( 2 <= r && r <= digits.size() ) radix = r; } //used internally at initialization, but can be used to reinitialize digits static std::vector<char> generateInitialDigits() { char arr[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; const unsigned int N = sizeof(arr) / sizeof(char); std::vector<char> digits; digits.reserve(N); for( int i = 0; i < N; i++ ) digits.push_back( arr[i] ); return digits; } //converts n into a unique permutation of digits virtual std::string toString() const { //check for the exceptional case if( n == 0 ) return std::string(1, digits[0]); //determine the number of digits needed to represent this permutation unsigned int len = 0; len = 1 + (int)( log((double)n) / log((double)radix) ); //allocate memory to hold the string representation of our permutation char *str = new char[len + 1]; //adding 1 for the null terminator '\0' str[len] = '\0'; //figure out each digit using division (both the quotient and remainder) unsigned long long k = n; //make a modifiable copy of n for( unsigned int i = len - 1; k > 0; i-- ) { str[i] = digits[k % radix]; k /= radix; //repeating until k == 0 } //convert char[] to C++ string, and return std::string r = str; delete[] str; return r; } }; //initialize static fields std::vector<char> N::digits = N::generateInitialDigits(); unsigned int N::radix = 10; //overloaded iostream operators std::ostream& operator<<(std::ostream &out, const N &num) { return out << num.toString(); } std::istream& operator>>(std::istream &in, N &num) { unsigned long long k; in >> k; num.n = k; return in; } #endifOutput:Code:#include <iostream> #include "N.h" using namespace std; void report(const N &n) { cout << "Base " << N::getRadix() << ": " << n << endl; } int main() { //create a number, and represent it in different bases N n = 200; report(n); N::setRadix(2); report(n); N::setRadix(5); report(n); N::setRadix(16); report(n); //what happens when we try to change to a base too big or too small N::setRadix(20); report(n); N::setRadix(1); report(n); //how is zero represented N zero = 0; report(zero); return 0; }Code:Base 10: 200 Base 2: 11001000 Base 5: 1300 Base 16: C8 Base 16: C8 Base 16: C8 Base 16: 0
No problem. I learned it in school somewhere, I'm sure. (Maybe in my assembly class...?) I'm a dual Math and CS major, so it's not the first time the problem has come up for me, (that is once I figured out what it was you were trying to do )
Let me know if you have any questions about the code BTW.
I encountered another problem.
Is the code i am using, based on the algorithm you showed me.Code:#include <cmath> #include <string> string _C(unsigned long long r,unsigned int n,unsigned short r1){ string s; unsigned short l = log(r)/log(n)+1; s.resize(l); while(l>0){s[--l] = (r%n) + r1;r/=n;} return s; }
The problem is the value (unsigned long long)~0, which is the longest native C++ datatype. Is too small for what i want to do (which is as much lenght as memory available).
The solutions i have come up with is:
1. Arithmetic on strings representing numbers.
2. A number representing how many times to multiply (unsigned long long)~0, in addition to an unsigned long long variable that holds the value between 0 and (unsigned long long)~0.
In 2, i would represent a number with amount*(unsigned long long)~0 + n. How would i do modulo on a representation like this? (where amount is the amount of (unsigned long long)~0, and n is the value between 0 and (unsigned long long)~0)
1 would mean creating the algorithm for addition, division, modulo from scratch.Code://Edit, i think i solved how to do modulo. unsigned n = 3 unsigned amount = 4; unsigned modulo = 0; for(unsinged l = 0;l++<amount;modulo+=(unsigned long long)~0 % 10); modulo+=n % 10;
Code:#include <sdtring> #include <cmath> #include <iostream> using namespace std; class Number{ public: unsigned long long n, m; Number() : n(0), m(0) {} unsigned long long operator%(unsigned long long e){ unsigned long long modulo = n%e, l = 0; while(l++<m)modulo+=(unsigned long long)~0 % e; return modulo; } Number& add(unsigned long long a,unsigned long long b){ if ( (double)a / (unsigned long long)~0 + (double)n / (unsigned long long)~0 <=1 ) n+=a, m+=b; else ++m, n = (unsigned long long)~0 - n; } Number& operator/=(unsigned long long a){ //I guess the question now is how i would do division? } }; void generate(unsigned long long r,unsigned int n, unsigned int _1){ string s; unsigned int l = log(r)/log(n)+1; s.resize(l); while(l>0){s[--l]=r%n+_1;r/=n;} cout<<s<<endl; } int main (){ generate(99999999,25,65); return 0; }
Sorry, I've been busy: google "c++ bigint"
"Big Integers" are a common type in programming for arbitrary sized ints, i.e. ints that can take up as much memory as the computer has.
The main idea is to store the numbers in base 256, each "digit" being a byte in memory; then store that number as an array of bytes (each element being a digit.)