.......1234
.....*1234
-------------
.......4936
.....3702
...2468
.1234
-------------
.1522756
t_stewart1012 0 Newbie Poster
Edited by t_stewart1012 because: n/a
Dani AI
Generated
wanted the classic long-multiplication layout; supplied a working C-style solution and pointed out tracking spacing with a variable. The main missing points are a safe, scalable way to compute the print width before emitting any lines, and handling edge cases (zeros, negative inputs, varying digit counts) without fixed-size buffers.
Algorithm summary to implement reliably:
- Work with absolute values to compute partial products; keep sign separate if needed.
- Extract multiplier digits right-to-left; compute each partial product = multiplicand * digit.
- Determine the overall column width as the maximum of:
- length of multiplicand,
- length of "*" + multiplier,
- length of any partial product plus its offset (digit index),
- length of the final product (including minus sign).
- Print lines right-aligned to that width, using a chosen pad character (dot) and dashes for separators.
- Ensure every multiplier digit (including zeros) produces a printed partial line.
A compact modern-C++ example implementing that approach:
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
void print_long_multiplication(int a, int b, char pad = '.')
{
using ll = long long;
ll A = std::llabs((ll)a);
ll B = std::llabs((ll)b);
std::string sA = std::to_string(A);
std::string sB = std::to_string(B);
std::vector<int> digits;
if (B == 0) digits.push_back(0);
for (ll tmp = B; tmp; tmp /= 10) digits.push_back(int(tmp % 10));
std::vector<ll> partials;
for (int d : digits) partials.push_back((ll)A * d);
ll total = (ll)a * b;
size_t width = std::max(sA.size(), sB.size() + 1);
for (size_t i = 0; i < partials.size(); ++i)
width = std::max(width, std::to_string(partials[i]).size() + i);
width = std::max(width, std::to_string(std::llabs(total)).size());
auto print_right = [&](const std::string &str, size_t offset = 0) {
std::cout << std::string(width - str.size() - offset, pad) << str
<< std::string(offset, ' ') << '\n';
};
print_right(sA);
print_right(std::string(1, '*') + sB);
std::cout << std::string(width, '-') << '\n';
for (size_t i = 0; i < partials.size(); ++i)
print_right(std::to_string(partials[i]), i);
std::cout << std::string(width, '-') << '\n';
print_right(std::to_string(total));
} Troubleshooting tips: precompute width before printing; treat multiplier zeros as real partial lines; use 64-bit integers if you plan to scale beyond four-digit inputs; and prefer std::string/std::ostringstream over fixed char buffers to avoid overflows.
Recommended Answers
Jump to Post— WaltP 2,905By keeping track of your spacing with a variable.
All 2 Replies
Alcaro -2 Newbie Poster
Not sure if I understood that format properly...
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_WARNINGS//to remove some annoying warnings my compiler keeps generating
#include <iostream>
using namespace std;
void output(const char * output)
//you might want to change this
{
cout<<output<<endl;
}
void multiply_frmt(int num1, int num2, int width)
//num1 and num2 are the two values to multiply it with
//width is how wide a line is. MUST BE WIDE ENOUGH OR A BUFFER WILL OVERFLOW.
{
char thisLine[32];//change these numbers if needed (I don't think it should)
char theDots[32];
char theSpaces[32];
char theNumbers[8];//you shouldn't need more than eight digit numbers... right?
sprintf(thisLine, "%i", num1);
for (int i=0;i<width;i++) theDots[i]='.';
theDots[width]=0;
strcpy(theDots+width-strlen(thisLine), thisLine);
output(theDots);
sprintf(thisLine, "*%i", num2);
for (int i=0;i<width;i++) theDots[i]='.';
theDots[width]=0;
strcpy(theDots+width-strlen(thisLine), thisLine);
output(theDots);
for (int i=0;i<width;i++) theDots[i]='-';
theDots[width]=0;
output(theDots);
int tmpNum=num1;
int theLength;
for (theLength=0;tmpNum;theLength++)
{
int tempNum=tmpNum;
tmpNum/=10;
theNumbers[theLength]=tempNum-(tmpNum*10);//this is some sort of rounding function
}
theSpaces[0]=0;
for (int i=0;i<theLength;i++)
{
sprintf(thisLine, "%i%s", num1*theNumbers[i], theSpaces);
for (int i=0;i<width;i++) theDots[i]='.';
theDots[width]=0;
strcpy(theDots+width-strlen(thisLine), thisLine);
output(theDots);
strcat(theSpaces, " ");
}
for (int i=0;i<width;i++) theDots[i]='-';
theDots[width]=0;
output(theDots);
sprintf(thisLine, "%i", num1*num2);
for (int i=0;i<width;i++) theDots[i]='.';
theDots[width]=0;
strcpy(theDots+width-strlen(thisLine), thisLine);
output(theDots);
}
int main()
//you propably want to edit this
{
multiply_frmt(1234, 1234, 11);
output("");
multiply_frmt(4321, 4321, 10);
return 0;
} This compiles without warnings and gives identical output in MSVC and mingw. You should be able to adapt it to your needs; if not, tell me.
WaltP commented: Another free lunch post -- and too complicated at that! -2
WaltP 2,905 Posting Sage w/ dash of thyme Team Colleague
By keeping track of your spacing with a variable.
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.