Create big numbers by BCD - C++ - c++

I want to create code that will help me get numbers bigger than MAXINT. I heard about that I can use Binary Code Decimal to do this, and then every two of decimal numbers(converted to BCD) of the bigger number keep in char. But how to do this? I should give string as input, then convert somehow to BCD every single decimal number? And how can I put two converted decimal numbers to one char? I'm new in C++ and don't know how can i do it.
P.S. I don't want to use libraries which are "special" for that kind of problems.

As it turns out, this is actually quite simple. How about we try to take it to the next level?
Below is an implementation of a BCD number with infinite(or as much as memory can hold) size. It only supports positive integer numbers. I'll leave extending this to support negative numbers(or real numbers) as an exercise.
First things first: Yes, we want to get our number as a string and then build it up from that. Since it's only an integer, this is actually quite easy to do. We primarily create a helper function to aid us in identifying all the digits.
int char_to_int(const char c) {
int ret = c - '0';
if(ret > 9 || ret < 0) throw 1; // for simplicity. Use a class derived from std::exception instead.
return ret;
}
We can now try to implement input and output for our big number.
First Try
Having that helper guy, turning a string to a BCD-encoded buffer is easy. A common implementation may look like this:
int main() {
unsigned char bignum[10]; // stores at most 20 BCD digits.
std::memset(bignum, 0, sizeof(bignum));
std::string input;
std::cin >> input;
try {
if (input.size() > 20) throw 1; // Avoid problems with buffer overflow.
for (int i=1;i<=input.size();i++) {
int n = char_to_int(input[input.size()-i]);
bignum[sizeof(bignum) - (i+1)/2] |= n << (i%2)*4; // These are bitwise operations. Google them!
}
}
catch(int) {
std::cout << "ERROR: Invalid input.\n";
return 0; // Exit cleanly.
}
// bignum is now filled. Let's print it to prove.
for (int i=0;i<sizeof(bignum);i++) {
int first_digit = bignum[i] & '\x0F'; // Right side, doesn't need to shift.
int second_digit = (bignum[i] & '\xF0')>>4; // Left side, shifted.
std::cout << first_digit << second_digit;
}
}
This is not very space-efficient, however. Note that we have to store all the 20 digits, even if our number is small! What if we needed 1000 digits? What if we need 1000 numbers that may or may not have these 1000 digits? It is also error-prone: Look that we had to remmember to initialize the array, and do a bounds check before conversion to avoid a buffer overflow.
Second Try
We can improve our implementation using a std::vector:
int main() {
std::vector<unsigned char> bignum; // stores any quantity of digits.
std::string input;
std::cin >> input;
try {
// For an odd number of digits we want a trailling zero at the end.
if(input.size()%2) n.num_vec.push_back(char_to_int(input[0]));
for (unsigned i=input.size()%2;i<input.size();i+=2) {
int left = char_to_int(input[i]);
int right = char_to_int(input[i+1]);
n.num_vec.push_back(0);
n.num_vec.back() = left << 4;
n.num_vec.back() |= right;
}
}
catch(int) {
std::cout << "ERROR: Invalid input.\n";
exit(0); // Exit cleanly.
}
// bignum is now filled. Let's print it to prove.
for (unsigned i=0;i<bignum.size();++i) {
// Notice that we inverted this from the previous one! Try to think why.
int first_digit = (bignum[i] & '\xF0')>>4; // Left side, shifted.
int second_digit = bignum[i] & '\x0F'; // Right side, doesn't need to shift.
if(i || first_digit) std::cout << first_digit; // avoid printing trailling 0.
std::cout << second_digit;
}
}
Lookin' good, but that is too cumbersome. Ideally, the bignumber user shouldn't have to deal with the vector positions and all that mumbo-jumbo. We want to write code that behaves like:
int main() {
int a;
cin >> a;
cout << a;
}
And it should just work.
Third Try
Turns out this is possible! Just wrap bignum into a class, with some helpful operators:
class bignum {
std::vector<unsigned char> num_vec;
template<typename T>
friend T& operator<<(T& is, bignum& n);
template<typename T>
friend T& operator>>(T& os, bignum& n);
};
// Get input from any object that behaves like an std::istream (i.e.: std::cin)
template<typename T>
T& operator>>(T& is, bignum& n) {
std::string input;
is >> input;
n.num_vec.reserve(input.size());
if(input.size()%2) n.num_vec.push_back(char_to_int(input[0]));
for (unsigned i=input.size()%2;i<input.size();i+=2) {
int left = char_to_int(input[i]);
int right = (i+1) != input.size()?char_to_int(input[i+1]):0; // If odd number of digits, avoid getting garbage.
n.num_vec.push_back(0);
n.num_vec.back() = left << 4;
n.num_vec.back() |= right;
}
return is;
}
// Output to any object that behaves like an std::ostream (i.e.: std::cout)
template<typename T>
T& operator<<(T& os, bignum& n) {
for (unsigned i=0;i<n.num_vec.size();++i) {
int first_digit = (n.num_vec[i] & '\xF0')>>4; // Left side, shifted.
int second_digit = n.num_vec[i] & '\x0F'; // Right side, doesn't need to shift.
if(i || first_digit) os << first_digit; // avoid printing trailling 0.
os << second_digit;
}
return os;
}
Then our main function looks much more readable:
int main() {
bignum a;
try {
std::cin >> a;
}
catch(int) {
std::cout << "ERROR: Invalid input.\n";
return 0; // Exit cleanly.
}
std::cout << a;
}
Epilogue
And here we have it. Of course with no addition, multiplication, etc. operators, it isn't very useful. I'll leave them as an exercise. Code, code and code some more, and soon this will look like a piece of cake to you.
Please feel free to ask any questions. Good coding!

Related

"Industrial Strength" C++ struct

It's been a while since I used C++. I was asked for job interview to create a C++ struct for a downsampling routine which would meet the following interface:
struct deterministic_sample
{
deterministic_rate( double rate );
bool operator()();
};
-- with the following behaviour:
We have an object of that class: deterministic_sample s;
We call s() N times, and it returns true, M times. M / N is roughly equal to the rate
The sequence is deterministic, not random and should be the same each time
The class should be "industrial strength", for use on a busy stream.
My solution, version 2:
#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
struct deterministic_sample
{
double sampRate;
int index;
deterministic_sample() {
sampRate = 0.1;
index = 0;
}
void deterministic_rate( double rate ) {
this->sampRate = rate; // Set the ivar. Not so necessary to hide data, but just complying with the interface, as given...
this->index = 0; // Reset the incrementer
};
bool operator()() {
if (this->index == INT_MAX) {
this->index = 0;
}
double multiple = this->index * this->sampRate;
this->index++; // Increment the index
if (fmod(multiple, 1) < this->sampRate) {
return true;
} else {
return false;
}
};
};
int main()
{
deterministic_sample s; // Create a sampler
s.deterministic_rate(0.253); // Set the rate
int tcnt = 0; // Count of True
int fcnt = 0; // Count of False
for (int i = 0; i < 10000; i++) {
bool o = s();
if (o) {
tcnt++;
} else {
fcnt++;
}
}
cout << "Trues: " << tcnt << endl;
cout << "Falses: " << fcnt << endl;
cout << "Ratio: " << ((float)tcnt / (float)(tcnt + fcnt)) << endl; // Show M / N
return 0;
}
The interviewer said this v2 code "partly" addressed the requirements. v1 didn't have the constructor (my error), and didn't deal with overflow of the int ivar.
What have I missed here to make this class robust/correct? I think it is some aspect of "industrial strength" that I've missed.
ps. for any ethical types, I've already submitted my second-chance attempt... It's just bothering me to know why this was "partly"...
What you have is far more complex than necessary. All you need to do is keep track of the current position, and return true when it goes past the threshold.
struct deterministic_sample
{
double sampRate;
double position;
deterministic_sample() : sampRate(0.1), position(0.0) {
}
void deterministic_rate( double rate ) {
assert(rate <= 1.0); // Only one output is allowed per input
sampRate = rate; // Set the ivar. Not so necessary to hide data, but just complying with the interface, as given...
// No need to reset the position, it will work with changing rates
};
bool operator()() {
position += sampRate;
if (position < 1.0)
return false;
position -= 1.0;
return true;
}
};
Use unsigned and integer overflow is a well-defined wraparound. This is very fast on normal CPU's.
The second problem I see is the mix of floating-point and integer math. That's not really efficient. It may be more efficient to store multiple as a member and just do multiple += rate. This saves you one integer to double conversion.
However, the fmod is still quite expensive. You can avoid that by keeping int trueSoFar instead. Now the rate so far is double(trueSoFar)/double(index) and you can check double(trueSoFar)/double(index) > rate or more efficiently trueSoFar> int(index * rate). As we already saw, rate*index can be replaced by multiple += rate.
This means we have one double addition (multiple +=), one FP to int conversion int(multiple) and one integer comparison.
[edit]
You can also avoid FP math altogether by keeping a 32/32 rational approximation of rate, and comparing that to the realised rate (again stored as a 32/32 ratio). Since a/b > c/d when a*d > b*c you can use a 64 bit multiply here. Even better, for the target ratio you can choose 2^32 as a fixed denominator (i.e. unsigned long targetRate = rate*pow(2^32), b=2^32 implicit) so that you now have unsigned long(unsigned long long(a)*index) >> 32) > trueSoFar. Even on a 32 bit CPU, this is fairly quick. >>32 is a no-op there.
OK, so it seems there are some improvements to the efficiency which could be made (certainly), that "industrial strength" has some implications though nothing concrete (possibly the problem...), or that the constructor was incorrectly named in the question (also possible).
In any case, no one has jumped on some glaring omission that I made to my constructor (like, I see there are two ways to do a C++ constructor; you should do both to be really bullet-proof, etc.)
I guess I'll just cross my fingers and hope I still progress to the soft-skills interview!
Thanks all.

Taking in array of unknown size in c++

Ok I am extremely new to programming, and I am taking a c++ class. Basically for the current project I have to take in an array of unknown size, resize it, and output a bunch of statistics like average, Q1, Q3, etc. I am having trouble taking in the array from the user. I need to quit taking in variables once they enter 0. Here is what I have:
int i = 1; //When I first posted this I didn't mean to comment out the '= 1' part
do {
cin >> array[i];
if (array[i] != 0)
return true;
} while (true);
What am I doing wrong? the program stops after I enter 1 number every time no matter what number I enter.
I am using vector class btw.
Do the following:
// change int to your type
int val;
std::vector<int> vec;
while(std::cin >> val) {
if(val == 0) break;
vec.push_back(val);
}
Reason: Stating a return clause causes to exit the loop.
use of std::vector ensures the arbitrary size condition.
Update after #nonsensickle's constructive remark:
The following piece of code also ensures the only 0 terminates input process condition:
// change int to your type
int val;
std::vector<int> vec;
do {
if(std::cin >> val) {
if(val == 0) break;
vec.push_back(val);
} else { // fix broken input stream in case of bad input
std::cin.clear();
std::cin.ignore(1,'\n');
}
} while(true);
and a more sophisticated way, although overkill but what the hell :), with templates and type traits:
template <typename T>
struct zero_traits
{
static T getzero() { return T(0); }
};
template <>
struct zero_traits<std::string>
{
static std::string getzero() { return "0"; }
};
template <>
struct zero_traits<char>
{
static char getzero() { return '0'; }
};
template <typename T>
std::vector<T> read_values()
{
T val;
std::vector<T> vec;
do {
if(std::cin >> val) {
if(val == zero_traits<T>::getzero()) break;
vec.push_back(val);
} else {
std::cin.clear();
std::cin.ignore(1,'\n');
}
} while(true);
return vec;
}
int main()
{
// change int to your type
std::vector<int> vec = read_values<int>();
for(auto i : vec) std::cout << i << std::endl;
}
First of all i will never increment.
Second of all, if (array[i] != 0) will return if that array's value doesn't equal 0.
You need to read into how do { ... } while() loops work as well as what return statements do. Might as well throw in how to increment an array while you're at it.
I will not try to answer your question directly. What you have is a small logic error and a misunderstanding of the do {...} while () looping construct. What you need is to learn how to step through your code.
Let's go through your code line by line (there are only 6 lines here so it should be really easy):
int i; - Ok, so we are declaring an integer i here but are not giving it a value. As such, i can have a random value.
do { - This is where we will come back to when we evaluate the while clause. But only if the result of the while clause is true.
cin >> array[i] - Store a value that the user enters in the array at the position i. Here we ask ourselves a question, what is i? We should know its value without having to run the program. Hint: there's a problem here because of i
if (array[i] != 0) - If the number entered by the user is not zero return true (exit this function with the result true).
} while (true); - Go back to the do { line and redo all the steps until you get here. There is no condition here so it will keep happening until we exit this function.
Hint: The only exit point of your loop is at step 4.
With this, you should be able to figure out your problem. Trying to break down the problem for yourself should be your first step.
I recommend reading this blog post on debugging small programs. It should be informative.
Though code posted by others (in particular #DimitriosBouzas) will work, and is the better choice, I strongly recommend fixing your code and learning why it failed. This will help you in the long run more than #DimitriosBouzas' elegant solution.
Before answering your question.
Initialize your variables int i=0; .You assign i to be zero because arrays are zero indexed.
You have to incerement i. If do not increment it, i will point at the first "bucket" in your array the whole time. Use i++ or i = i + 1 after every iteration of the do while loop to move "forward" in your array.
You want your program to run until zero is entered so you have to write your condition like this if (array[i] == 0) return true;. This condition is true when the last number entered was zero and it will cause your method to return. It would be more elegant for you to check for it in the while clause.
Putting it all together, your code should look like this
int i=0;
do {
cin >> array[i];
if (array[i] != 0) break;
i++;
} while (i < maxSize);
//do stuff with filled array

using C++ list library as a linked list

I am trying to make a farey seq program with C++ list library
My program works fine when I use the first level, however, it crashes after that with all other levels for some reason.
I am using visual studio as a compiler. I tried the debugger mode as well as the resource.
The program doesn't crash in the resource mode, however, it doesn't give me the even numbers levels output. In addition, it gives me half of the odds levels output for some reason.
I want to fix this problem and I want it to work in the dubgger mode as well.
Any suggestions?
Here is what I've done so far
class RULLZ: public list<Fraction>
{
private:
list<Fraction>::iterator head,tail,buf,buf1;
public :
Farey2()
{
this->push_front( Fraction(1,1));
this->push_front( Fraction(0,1));
}
void Add(int level)
{
Fraction *tmp,*tmp2;
buf=this->first();
for(int i=0;i<level-1;i++)
{
head=this->first();
tail=this->last();
while(head!=tail)
{
tmp=new Fraction(head->num,head->den);
head++;
if(tmp->den+head->den<=level)
{
tmp2=new Fraction(tmp->num+head->num,tmp->den+head->den);
this->insert(head,*tmp2);
head--;
}
}
this->pop_back();
}
}
friend ostream& operator<<(ostream& out, RULLZ& f)
{
for(list<Fraction>::iterator it=f.first();it !=f.last();it++)
out <<*it;
return out;
}
};
class RULLZ: public list<Fraction>
Before even looking at your question, the above code is a problem. The C++ standard containers are deliberately not designed to be base classes (none of them have a virtual destructor), so this will cause problems. For reasons why you should not publicly derive from a standard container, see the following:
When is it "okay"?
The risks
Why it is a bad design decision
Coding Guidelines (Page ~60)
Why inheritance is usually not the right approach
It appears you want the Add function to add the next X number of fractions together (if I understand your intent correctly). A better way to do that is to use a std::stack:
std::stack<Fraction, std::list<Fraction>> expression;
// add fractions to your stack here
Fraction Add(unsigned int count)
{
// assume count is greater than 1 (as adding 0 fractions makes no sense, and adding 1 is trivial)
Fraction result(0, 1);
for (int i = 0; i < count; ++i)
{
Fraction a = expression.top();
expression.pop();
Fraction b = expression.top();
expression.pop();
result += a + b; // assume operators + and += have been implemented for Fraction
}
expression.push(result);
return result;
}
Another problem you appear to have is a logic problem (again, assuming I understand your intent correctly):
for(int i=0;i<level-1;i++)
If level is the number of fractions you want to add, and you pass in 2, this loop will only include the first one. That is, it will not add fractions 0 and 1, but rather just grab fraction 0 and return it. I think you meant for this to be
for(int i=0; i < level; i++)
Which will grab both fractions 0 and 1 to add together.
I'm not sure where, but your logic for generating the series appears to be off. A more simple approach can be found here:
#include <algorithm>
#include <cstdint>
#include <iterator>
#include <iostream>
#include <vector>
struct Fraction
{
std::uint32_t Numerator;
std::uint32_t Denominator;
Fraction(std::uint32_t n, std::uint32_t d) : Numerator(n), Denominator(d) { }
};
std::ostream& operator<<(std::ostream& os, const Fraction& f)
{
os << "(" << f.Numerator << " / " << f.Denominator << ")";
return os;
}
typedef std::vector<Fraction> FareySeries;
FareySeries generate_series(std::uint32_t depth)
{
std::uint32_t a = 0;
std::uint32_t b = 1;
std::uint32_t c = 1;
std::uint32_t d = depth;
FareySeries results;
results.emplace_back(a, b);
while (c <= depth)
{
std::uint32_t k = (depth + b) / d;
std::uint32_t nc = (k * c) - a;
std::uint32_t nd = (k * d) - b;
a = c;
b = d;
c = nc;
d = nd;
results.emplace_back(a, b);
}
return results;
}
int main()
{
const std::uint32_t DEPTH = 4;
FareySeries series = generate_series(DEPTH);
std::copy(series.begin(), series.end(), std::ostream_iterator<Fraction>(std::cout, "\n"));
return 0;
}

How to write Console terminal with C++ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am studying for an exam and need your help.
I must write my own console terminal in C++, which must work in this way:
Example:
:>plus 5 7 "hit ENTER"
:>12
:>minus 10 12 "hit ENTER"
:>-2
:>combine Hello World "hit ENTER"
:>HelloWorld
:>run netstat "hit ENTER"
:>runs netstat
:>help
:>plus int1 int2
minus int1 int2
combine string1 string2
run ?????
:>exit
program exits
For main block I think it would be something like this
int main(void) {
string x;
while (true) {
getline(cin, x);
detect_command(x);
}
return 0;
}
The functions would be something like this
void my_plus(int a, int b) {
cout << a + b;
}
void my_minus(int a, int b) {
cout << a - b;
}
void my_combine(string a, string b) {
?????????????;
}
void my_run(?????????) {
???????????;
}
And the finally detect_command
void detect_command(string a) {
const int arr_length = 10;
string commands[arr_length] = { "plus", "minus", "help", "exit" };
for (int i = 0; i < arr_length; i++) {
if (a.compare(0, commands[i].length(), commands[i]) == 0) {
?????????????????????;
}
}
}
????? - means I don`t know what to write.
Help to make this program work.
Thanks.
I'm going to use the minus operation as an example...
Make a structure like so:
struct cmd_struct {
const char *name;
void (*func) (void *data);
};
Since your function parameters aren't the same, you gotta make a structure for each, e.g.:
struct minus_op {
int rhs;
int lhs;
};
And use the cmd_struct as an array, like so:
static cmd_struct commands[] = {
{ "minus", &my_minus },
...
};
my_minus would then be:
void my_minus(void *data) {
struct minus_op *mop = data;
... do the computation and return ...
}
And loop through it to detect the command used:
for (int i = 0; i < sizeof(commands) / sizeof(commands[0]); ++i) {
if (strcmp(commands[i].name, a) == 0) {
... prepare the data ...
commands[i].func(data);
}
}
Side Note: In order to get the function parameters from command line, have a splitter, e.g. a white space. Use a vector for this and pass that vector to detect_command
Do also note: Get rid of the void param used in this example and use a char **argv and int argc like in main(). argv would be the arguments, and argc would be the number of arguments passed to the function. e.g. if you say to the program:
>> minus 5 1
Then argc should be 2 (the 5 and the 1) and argv[0] = "5" and argv[1] = "1".
Now that you know the idea behind it, implementing a more flexible version is left to you.
Call a respective function to handle each word. For example:
enum commands {
PLUS,
MINUS,
HELP,
EXIT
//....
};
int detect_command(string a) {
const int arr_length = 10;
string commands[arr_length] = { "plus", "minus", "help", "exit" };
for (int i = 0; i < arr_length; i++) {
if (a.compare(0, commands[i].length(), commands[i]) == 0)
return i;
}
return -1; //unknow word
}
Give the string to detect_command() the function return the respective integer to enum commands (that's our i value) or -1 if word is unknow. Then you can write a function like this to use and process the value determined by detect_command():
void run_command(int cmd)
{
switch(cmd) {
case PLUS: run_plus(); break;
case MINUS: run_minus(); break;
// and so on to all comamnds available
default: error("unknow command");
}
}
each function run_*() should continues the command parsing according to own rules, i.e, the "plus" command should be follow by one integer, one white-space and then another integer, right? run_plus() must validate it and then compute the result. e.g.:
//pseudo code
void run_plus()
{
//input here is one after "plus" word
//here we must validate our valid input: two digits split by a white-spaces
int x = parse_digit();
check(white-space);
int y = parse_digit();
int r = x + y;
display_result(r);
}
NOTE: I'm not a C++ programmer; I did detect_command() code modification to you get my idea. I even don't know if it will compile in C++ for the mismatch types.

Assigning Private Variable within a constructor

I've read through stack overflow threads multiple times in the past, and they're often quite helpful. However, I've run into a problem that simply doesn't make sense to me, and I'm trying to figure out what I missed. Here's the sections of the code that I'm having trouble with:
class BigInts
{
public:
static const std::size_t MAXLEN = 100;
BigInts(signed int i); //constructor
BigInts(std::string &); //other constructor
std::size_t size() const;
digit_type operator[](std::size_t ) const;
private:
digit_type _data[MAXLEN];
bool _negative;
int _significant;
};
//nonmember functions
std::ostream & operator << (std::ostream &, const BigInts &);
BigInts::BigInts(signed int i)
{
_negative = (i < 0);
if (i < 0)
{
i = -1*i;
}
std::fill(_data, _data+MAXLEN, 0);
if (i != 0)
{
int d(0);
int c(0);
do
{
_data[d++] = ( i % 10);
i = i / 10;
c++; //digit counter
}while(i > 0);
//_significant = c; //The problem line
assert(c <= MAXLEN); //checks if int got too big
}
}
std::size_t BigInts::size() const
{
std::size_t pos(MAXLEN-1);
while (pos > 0 && _data[pos] == 0)
--pos;
return pos+1;
}
std::ostream & operator << (std::ostream & os, const BigInts & b)
{
for (int i = (b.size() - 1); i >= 0; --i)
os << b[i];
return os;
}
int main()
{
signed int a, b;
std::cout << "enter first number" << std::endl;
std::cin >> a;
std::cout << "enter second number" << std::endl;
std::cin >> b;
BigInts d(a), e(b), f(b);
std::cout << d << " " << e << " " << f;
Major edit, switched from an attempted dummy version of the code to the actual code I'm using, complete with the original variable names. I tried to remove anything that isn't relevant to the code I'm currently working with, but if you see a strange name or call in there, let me know and I can post the associated portion.
The code had been working fine prior to the introduction of _significant, which is a variable I had added to add some more functionality to the class as a whole. However, when I attempted to drive the basic parts of it using the main function you see displayed, it encountered large errors. For example, I inputted 200 and 100 for a and b respectively, it outputted 201, 1, and 3 for d, e, and f. As it currently stands, the ONLY place _significant appears is when I'm attempting to assign the value of c to it.
The only error I can see right now is that _significant isn't initialized when the input is zero.
Step through it in a debugger, make sure the the right digits are ending up in the array and that the array data isn't being overwritten unexpectedly.
EDIT: It works for me (cleaned up slightly). More cleaned up, also working: http://ideone.com/MDQF8
If your class is busted purely by assigning to a member variable, that means stack corruption without a doubt. Whilst I can't see the source offhand, you should replace all buffers with self-length-checking classes to verify accesses.
The line i - 1; in the original code looks highly suspicious. Did you want to write i -= 1; or --i; or something else?
It decrements i by 1 and then throws away the result.