Multiplying in C++

nephilim2k

Member
Apr 5, 2013
175
0
0
Hey guys. I am trying to write up a little piece of software where you input 1 number, it does a set of functions, and outputs an answer.

This is my code (I have added various bits and pieces to change the size of the utility box, and input number being 1 colour, output being another).

Function required is as follows

User inputs random number (we will call this N)
Function 1 is 987654-N = X
Function 2 is (first 4 digits of X) * X = Y
Function 3 is Last 4 digits of Y = End Result.

Can anyone help me with this and where I am going wrong? (I realise I have not done the function 3 completely yet, but the coding escapes me, and when building this, it halts on the multiplication section).

Code:
//Number Generator

#include <iostream>
#include <sstream>
#include <stdexcept>
#include <windows.h>

using namespace std;

void SetColor(int value){
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  value);
}
struct console
  {
  console( unsigned width, unsigned height )
    {
    SMALL_RECT r;
    COORD      c;
    hConOut = GetStdHandle( STD_OUTPUT_HANDLE );
    if (!GetConsoleScreenBufferInfo( hConOut, &csbi ))
      throw runtime_error( "You must be attached to a human." );
    r.Left   =
    r.Top    = 0;
    r.Right  = width -1;
    r.Bottom = height -1;
    SetConsoleWindowInfo( hConOut, TRUE, &r );
    c.X = width;
    c.Y = height;
    SetConsoleScreenBufferSize( hConOut, c );
    }
  ~console()
    {
    SetConsoleTextAttribute(    hConOut,        csbi.wAttributes );
    SetConsoleScreenBufferSize( hConOut,        csbi.dwSize      );
    SetConsoleWindowInfo(       hConOut, TRUE, &csbi.srWindow    );
    }
  void color( WORD color = 0x07 )
    {
    SetConsoleTextAttribute( hConOut, color );
    }
  HANDLE                     hConOut;
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  };
//Set Console Size
console con( 25, 10);

string ToUpper(string str)
{
    string converted;

    for(short i=0; i < str.size(); ++i)
        converted += toupper(str[i]);

    return converted;
}

bool run()
{
int iStart;
int iCalculated;
int iCalculated2;
int iCalculated3;
string sResponse;
bool isRunning = false;
bool dbg = false;
string sResult;
ostringstream convert;
SetColor (15);
cout << "Enter Number: ";
SetColor (12);
cin >> iStart;

//perform calculations
iCalculated = (987654 - iStart);
if (dbg)
    cout << "(987654 - " << iStart << ") = " << iCalculated << "\n";

//convert result to string
convert << iCalculated;
sResult = convert.str();

//prepend with 0's if neccessary
if (sResult.length() < 6)
{
string sZeroes;
sZeroes.append(6 - sResult.length(), '0');
sResult = sZeroes.append(sResult);
}

if (dbg)
    cout << "String converted and length fixed: " << sResult << "\n";

//rearrange string
sResult = sResult.substr(0,4);
//perform second set of calculations
cin >> sResult.substr * sResult = iCalculated2;
if (dbg)
    cout << "(sResult.substr * " << iCalculated2 << ") = " << iCalculated3 << "\n";


SetColor (15);
cout << "New Number: ";
SetColor (10);
cout << iCalculated3 << "\n";
SetColor (15);
cout << "Run again? (Y/N)" ;
cin >> sResponse;

sResponse = ToUpper(sResponse);
if (sResponse=="Y" || sResponse=="YES")
    isRunning=true;

return isRunning;
}

int main()
{
bool isRunning = true;

while (isRunning)
{
    isRunning = run();
}
}
 

nephilim2k

Member
Apr 5, 2013
175
0
0
Also, funds pending from my cheque clearing from work, there may be a beer or two for the person who can help (paid via paypal)
 

iCyborg

Golden Member
Aug 8, 2008
1,327
52
91
Code:
//perform second set of calculations
cin >> sResult.substr * sResult = iCalculated2;
I'm not sure what you're trying to do here, but for the love of God, don't do it like this. I don't even know how to parse this, the compiler should have issued a warning at least.
 

veri745

Golden Member
Oct 11, 2007
1,163
4
81
Separate your calculations from input and output.

For assignments (i.e. x = y ), the left-hand side (x) is being assigned to the value of the right-hand side (y), not the other way around.

This works:
Code:
x = 5 + 3
This doesn't:
Code:
 5 + 3 = x

iCalculated3 is never assigned a value.
 
Last edited:

nephilim2k

Member
Apr 5, 2013
175
0
0
So how would I do this then...

Function 1 - Input A = Result
Result * 1st 4 digits of Result = Result 2
Last 4 digits of Result 2 = Result 3
Output Result3

How? :(
 

OSULugan

Senior member
Feb 22, 2003
289
0
76
Try this for your run function. You'll need 64-bit in order to use it, since your 2nd number needs to be so large. Otherwise, it will get much more complicated.

Code:
bool run()
{
	long iStart;
	
	int iResultOneFirstFour;
	
	LONG64 iCalculated;
	LONG64 iCalculated2;
	LONG64 iCalculated3;
	
	string sResponse;
	bool isRunning = false;
	bool dbg = false;

	string sResult;
	ostringstream convert;

	SetColor (15);
	cout << "Enter Number: ";
	SetColor (12);
	cin >> iStart;

	//perform calculations
	iCalculated = (987654 - iStart);
	if (dbg)
		cout << "(987654 - " << iStart << ") = " << iCalculated << "\n";

	//convert result to string
	convert << iCalculated;
	sResult = convert.str();

	//prepend with 0's if neccessary
	if (sResult.length() < 6)
	{
		string sZeroes;
		sZeroes.append(6 - sResult.length(), '0');
		sResult = sZeroes.append(sResult);
	}

	if (dbg)
		cout << "String converted and length fixed: " << sResult << "\n";

	//rearrange string
	sResult = sResult.substr(0,4);
	//perform second set of calculations

	iResultOneFirstFour = atoi(sResult.c_str());
	iCalculated2 = iResultOneFirstFour * iCalculated;

	convert << iCalculated2;
	sResult = convert.str();

	if (sResult.length() < 6)
	{
		string sZeroes;
		sZeroes.append(6 - sResult.length(), '0');
		sResult = sZeroes.append(sResult);
	}

	sResult = sResult.substr(sResult.length()-4,4);

	iCalculated3 = atoi(sResult.c_str());

	if (dbg)
		cout << "(sResult.substr * " << iCalculated2 << ") = " << iCalculated3 << "\n";

	SetColor (15);
	cout << "New Number: ";
	SetColor (10);
	cout << iCalculated3 << "\n";
	SetColor (15);
	cout << "Run again? (Y/N)" ;
	cin >> sResponse;

	sResponse = ToUpper(sResponse);
	if (sResponse=="Y" || sResponse=="YES")
		isRunning=true;

	return isRunning;
}
 

douglasb

Diamond Member
Apr 11, 2005
3,163
0
76
So how would I do this then...

Function 1 - Input A = Result
Result * 1st 4 digits of Result = Result 2
Last 4 digits of Result 2 = Result 3
Output Result3

How? :(

Pay attention to the post directly above yours. He just gave you the answer. We aren't going to spoon-feed it to you.
 

OSULugan

Senior member
Feb 22, 2003
289
0
76
64bit could be a problem...

If you can't use a 64-bit value, then you're going to have to come up with a clever solution to only calculate the lowest 4 digits of the 2nd calculated number (as if you were doing long multiplication by hand). In this case, you can drop off all but the 1st and last 4 digits of the result from function 1.

See below. (Note: This doesn't handle the case where the result from function 1 is negative).

Code:
bool run()
{
	long iStart;
	
	int iResultOneFirstFour;
	int iResultOneLastFour;
	
	long iCalculated;
	long iCalculated2;
	long iCalculated3;
	
	string sResponse;
	bool isRunning = false;
	bool dbg = false;

	string sResult;
	string sFirstFour;
	string sLastFour;
	ostringstream convert;

	SetColor (15);
	cout << "Enter Number: ";
	SetColor (12);
	cin >> iStart;

	//perform calculations
	iCalculated = (987654 - iStart);
	if (dbg)
		cout << "(987654 - " << iStart << ") = " << iCalculated << "\n";

	//convert result to string
	convert << iCalculated;
	sResult = convert.str();

	//prepend with 0's if neccessary
	if (sResult.length() < 6)
	{
		string sZeroes;
		sZeroes.append(6 - sResult.length(), '0');
		sResult = sZeroes.append(sResult);
	}

	if (dbg)
		cout << "String converted and length fixed: " << sResult << "\n";

	//get 1st and last 4 digits extracted
	//since we only care about the final 4 digits of the answer,
	//we can discard all but the 4 digits on either end of the 1st result
	//which should allow us to avoid overflowing a 32-bit integer

	sFirstFour = sResult.substr(0,4);
	sLastFour = sResult.substr(sResult.length()-4,4);

	//perform second set of calculations

	//convert strings to integers
	iResultOneFirstFour = atoi(sFirstFour.c_str());
	iResultOneLastFour = atoi(sLastFour.c_str());

	iCalculated2 = iResultOneFirstFour * iResultOneLastFour;

	convert << iCalculated2;
	sResult = convert.str();

	if (sResult.length() < 6)
	{
		string sZeroes;
		sZeroes.append(6 - sResult.length(), '0');
		sResult = sZeroes.append(sResult);
	}

	sResult = sResult.substr(sResult.length()-4,4);

	iCalculated3 = atoi(sResult.c_str());

	if (dbg)
		cout << "(sResult.substr * " << iCalculated2 << ") = " << iCalculated3 << "\n";

	SetColor (15);
	cout << "New Number: ";
	SetColor (10);
	cout << iCalculated3 << "\n";
	SetColor (15);
	cout << "Run again? (Y/N)" ;
	cin >> sResponse;

	sResponse = ToUpper(sResponse);
	if (sResponse=="Y" || sResponse=="YES")
		isRunning=true;

	return isRunning;
}
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
If you can't use a 64-bit value, then you're going to have to come up with a clever solution to only calculate the lowest 4 digits of the 2nd calculated number (as if you were doing long multiplication by hand). In this case, you can drop off all but the 1st and last 4 digits of the result from function 1.

Hint: Find out what '%' does.
 

piasabird

Lifer
Feb 6, 2002
17,168
60
91
Try outputting the result at each step so you can see what is going on. If you have 2 very large numbers will the result fit in your variable size. I wrote a program once for a TI-83 CALCULATOR that kept all the variables in text fields or arrays and it took one text mumeral out at a time computed that colum and the result was stored one digit at a time in a new text array as text. The object was to divide numbers without the result being truncated so if the answer had 100 decimal points it could still be computed to a set number of digits.

C++ has built-in functions for taking text in and doing text math.

Maybe I am wrong about this. These could only exist in borland or maybe they were made up at the time.
 
Last edited:

nephilim2k

Member
Apr 5, 2013
175
0
0
I was thinking, Perhaps I can set a seed to be one of the functions...will work on it, if I crack it, I will post up the code for all to see.
 

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,591
5
0
User inputs random number (we will call this N)
Function 1 is 987654-N = X
Function 2 is (first 4 digits of X) * X = Y
Function 3 is Last 4 digits of Y = End Result.

First thing - break the problem into little pieces and attack each piece

  • The input of N is a string - You need it as a number.
  • X & Y are numbers - you need them also as strings or be able to divide and get the results :p
  • You need to extract substrings
 
Last edited:

mv2devnull

Golden Member
Apr 13, 2010
1,501
145
106
User inputs random number (we will call this N)
Function 1 is 987654-N = X
Function 2 is (first 4 digits of X) * X = Y
Function 3 is Last 4 digits of Y = End Result.
Just to be sure, with an example. The user types "123456789". That is N.
987654 - 123456789 = -122469135 = X
Xp = 1224
Xp * X = 1224 * -122469135 = -149902221240 = Y
Ys = 1240 = End Result

Notes:
* A naive "get most significant digits from string representation" is likely to fail here.
* Unnecessary overflow of Y can be avoided, since only the least significant digits are used. The operator % has already been mentioned.
 

nephilim2k

Member
Apr 5, 2013
175
0
0
ok, well in this argument, the input number will be 6 digits, and not start higher than a 5...so anything from 100000 to 599999 are the input numbers. the multiplication of first 4 digits by the whole answer will not be larger than 10 digits (as per my math)...
 

nephilim2k

Member
Apr 5, 2013
175
0
0
Total code constructed, and works (tested outputs)

Code:
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <windows.h>

#define SEED 987654
#define DBG false

using namespace std;

void SetColor(int value){
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),  value);
}

//prepends a given string with a given character if it's length is less than a given number
string PrePadString(string str, int length, char pad)
{
    if (str.length() < length)
	{
		string sZeroes;
		sZeroes.append(length - str.length(), pad);
		str = sZeroes.append(str);
	}

	return str;
}

struct console
  {
  console( unsigned width, unsigned height )
    {
    SMALL_RECT r;
    COORD      c;
    hConOut = GetStdHandle( STD_OUTPUT_HANDLE );
    if (!GetConsoleScreenBufferInfo( hConOut, &csbi ))
      throw runtime_error( "You must be attached to a human." );
    r.Left   =
    r.Top    = 0;
    r.Right  = width -1;
    r.Bottom = height -1;
    SetConsoleWindowInfo( hConOut, TRUE, &r );
    c.X = width;
    c.Y = height;
    SetConsoleScreenBufferSize( hConOut, c );
    }
  ~console()
    {
    SetConsoleTextAttribute(    hConOut,        csbi.wAttributes );
    SetConsoleScreenBufferSize( hConOut,        csbi.dwSize      );
    SetConsoleWindowInfo(       hConOut, TRUE, &csbi.srWindow    );
    }
  void color( WORD color = 0x07 )
    {
    SetConsoleTextAttribute( hConOut, color );
    }
  HANDLE                     hConOut;
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  };
//Set Console Size
console con( 25, 10);

string ToUpper(string str)
{
    string converted;

    for(short i=0; i < str.size(); ++i)
        converted += toupper(str[i]);

    return converted;
}

bool run()
{
unsigned int iStart;
unsigned int x;
unsigned __int64 y;

string sResponse;
bool isRunning = false;
string sResult;
ostringstream convert;

SetColor (15);
cout << "Enter Passcode: ";
SetColor (12);
cin >> iStart;

//perform calculations
x = (SEED - iStart);
if (DBG)
    cout << "X = (" << SEED << " - " << iStart << ") = " << x << "\n";

y = x;

//convert result to string
convert << y;
sResult = convert.str();

//extract and convert first 4 digits
sResult = PrePadString(sResult, 4, '0');
sResult = sResult.substr(0, 4);
y = atoi(sResult.c_str());

//perform final calculation
y = y * x;

if (DBG)
    cout << "Y = " << sResult << " x " << x << " = " << y << "\n";

//convert to string and extract last 4 digits
convert << y;
sResult = convert.str();
sResult = PrePadString(sResult, 4, '0');
sResult = sResult.substr(sResult.length() - 4, 4);

SetColor (15);
cout << "New Passcode: ";
SetColor (10);
cout << sResult << "\n";
SetColor (15);

return true;
}

int main()
{
bool isRunning = true;

while (isRunning)
{
    isRunning = run();
}
}


I appreciate all of the help guys
 

mv2devnull

Golden Member
Apr 13, 2010
1,501
145
106
ok, well in this argument, the input number will be 6 digits, and not start higher than a 5...so anything from 100000 to 599999 are the input numbers. the multiplication of first 4 digits by the whole answer will not be larger than 10 digits (as per my math)...
Your program does not tell to the user, check for, nor enforce the valid range of input [100000..599999]. It should. User can make an honest mistake and then the program should handle the error.

Can you estimate, what the following do:
Code:
[FONT=Verdana]unsigned int Ys = ( Xp * ( X % 100 ) ) % 100;[/FONT][FONT=Verdana]
std::cout << std::setfill ('0') << std::setw (2) << Ys;[/FONT]
Code:
#define SEED 987654
#define DBG false
Have you seen this construct:
Code:
const unsigned int SEED = 987654;
const bool DBG = false;
Avoid unnecessary macros.
 

nephilim2k

Member
Apr 5, 2013
175
0
0
Good point. I will change the first input line. This should resolve any lingering issues about that.
 

sm625

Diamond Member
May 6, 2011
8,172
137
106
Your code is barely legible. It could be simpler looking, for example:
Code:
	#define SEED 987654

	CString str;
	long nStep1;
	long nStep2;
	long nStep3;

	long N = GetInputFromUser();

	if(N > 599999)
		DoErrorMsg(N);
	if(N < 100000)
		DoErrorMsg(N);

	//do function 1
	nStep1 = SEED-N;

	//do function 2
	str.Format("%d",nStep1);
	sscanf(str.Left(4),"%d",&nStep2);
	nStep2 *= nStep1;

	//do function 3
	str.Format("%d",nStep2);
	sscanf(str.Right(4),"%d",&nStep3);

	DisplayResult(nStep3);