.......1234
.....*1234
-------------
.......4936
.....3702
...2468
.1234
-------------
.1522756

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

All 2 Replies

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.

commented: Another free lunch post -- and too complicated at that! -2

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.