0

Referring to the below question, How to concatenate two integers in C

unsigned concatenate(unsigned x, unsigned y) {
    unsigned pow = 10;
    while(y >= pow)
        pow *= 10;
    return x * pow + y;        
}

How do I get the original values for x and y without using arrays? I need less processing overhead.

Geeta Naik
  • 11
  • 2
  • 7
    You can't get original numbers. What will be original numbers of `1234`? `1` and `234`? Or `12` and `34`? Or `123` and `4` ? – Eugene Sh. Sep 27 '21 at 13:46
  • 1
    Who will post the answer: "Impossible" ? – Support Ukraine Sep 27 '21 at 13:55
  • I don't see how you can without preserving the value of `pow`, then if `pow` is 10 you just lop of the last digit, if `pow` is 100 you lop off the last two digits, etc. If you preserve `pow` then the value after lopping off the digits is `x` and the lopped digits is `y` – LEF Sep 27 '21 at 13:59
  • You get the original numbers back by using a different answer to [that other question](https://stackoverflow.com/questions/12700497). `x * pow + y;` is wrong. `x * 100 + y` is correct, even though the other questions' answers unaccountably disdain it. – Steve Summit Sep 27 '21 at 16:29

3 Answers3

1

How do I get the original values for x and y without using arrays?

Information is lost. To reconstruct x,y addtional infomation is needed.

Example 1234 could have beeen formed by

x    y
123  4
12   34
1    234
0    1234

Aside: Improved answer on the original concatenation problem.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

You pass two arguments to concatenate().
If you pass two arguments to unconcatenate() you can get your numbers back:

void unconcatenate(unsigned *first, unsigned *second, unsigned concatenated, unsigned limit) {
    unsigned pow = 10;
    while (pow < limit) pow *= 10;
    *first = concatenated / pow;
    *second = concatenated % pow;
}

unsigned x, y, foo = concatenate(1234, 56);

unconcatenate(&x, &y, foo, 100);
printf("%u unconcatenaded to %u and %u.\n", foo, x, y);

see https://ideone.com/bg7qMd

pmg
  • 106,608
  • 13
  • 126
  • 198
  • 2
    Not too bad, yet `unconcatenate()` will be a problem in edge cases like `concatenate(0, 1234567890)` where `limit` needs to be more than `INT_MAX` (e.g. 10,000,000,000). – chux - Reinstate Monica Sep 27 '21 at 14:59
0

I haven't commented on it yet, but that original question makes no sense to me.

In my experience, at least, the goal is to concatenate numbers with a known, fixed number of digits. For example, if I have

int year = 2021;
int month = 10;
int day = 2;

(that is, a date next month), and I want to "concatenate" them, the desired result is of course 20211002. It would be quite wrong to output 2021102 — because nobody could tell whether it was supposed to be October 2, or maybe January 2!

At the other question, there's a comment that "100 * x + y fails when y == 0", as if concatenating 23 and 0 should yield 230, or maybe 23, but that sounds crazy to me.

Since the question here is about getting the original values back, the answer is obviously to know how many digits each original number had. For example, if you know you have two 2-digit numbers x and y, then z = 100 * x + y is absolutely the right way to concatenate them. And then, having done so, getting the original values back is equally straightforward:

x = z / 100;
y = z % 100;

The key is that we picked that magic number 100, that effectively sets y as 2 digits, in advance, and baked it into the code. We did not, as some of the answers at the other question (and the code fragment in this question here) suggest, dynamically and empirically discover a scaling factor at run time by doing successive multiplications by 10. (And by not doing those successive multiplications to compute pow every time, we'll have less processing overhead, too.)

Summary: while(y >= pow) pow *= 10; is the wrong way to concatenate numbers in C. The right way is

z = 100 * x * y;

and once you've done it that way, you get the original numbers back by doing

x = z / 100;
y = z % 100;

If y might have more digits, pick an appropriate multiplier greater than 100, and use that instead. And do be mindful that if you're not careful, your concatenated number can end up bigger than an ordinary int will hold.


P.S. I said "if you know you have two 2-digit numbers x and y", but that's not quite right. If you're using 100 * x + y, then y has to be two digits (or less), but it's okay for x to be more than 2 digits (within limits).

Steve Summit
  • 45,437
  • 7
  • 70
  • 103