Concatenate two integers in Mathematica 7
Asked Answered
E

2

9

What is the most efficient way to concatenate two positive integers in Mathematica 7?

cc[123, 4567] >> 1234567

What about more than two?

cc[123, 4, 567, 89] >> 123456789

Evangelistic answered 23/5, 2011 at 10:28 Comment(0)
A
9

This will be slightly faster for many integers, than your last solution:

ToExpression[StringJoin @@ Map[IntegerString, {##}]] &

A more concise alternative is to accept a single argument, assuming it to be a list, rather than a sequence, of numbers to concatenate:

ToExpression@StringJoin@IntegerString@#&

which is based on IntegerString being Listable.

Alaniz answered 23/5, 2011 at 10:59 Comment(0)
E
3

This only works properly for short integers because the output must be machine size, but it is the fastest I found:

Compile[{{a, _Integer}, {b, _Integer}}, 
  b + a 10^Floor[1 + Log[10, b]]
]

For longer integers, the fastest I could find is:

FromDigits[{##}, 10^IntegerLength@#2] &

For concatenating many integers, the following was faster than Fold on the one above:

FromDigits[Join @@ IntegerDigits[{##}]] & 
Evangelistic answered 23/5, 2011 at 10:29 Comment(9)
In my timings the use of IntegerLength[b] in the compiled function is 20 times faster than the use of Floor[...] .Bandit
@Sjoerd, is that in version 8?Evangelistic
@Evangelistic Fold is slow because it ends up multiplying small integers by large ones a lot for long arrays. You can get a factor of 2 speed up by using divide and conquer: Clear[cc4]; cc4[{i_}] := i; cc4[{i1_, i2_}] := FromDigits[{i1, i2}, 10^IntegerLength[i2]]; cc4[x_List] := With[{k = Quotient[Length[x] + 1, 2]}, cc4[{cc4[Take[x, k]], cc4[Drop[x, k]]}] ].Bini
@Mr.wizard V8, but I tried again and don't seem to be able to reproduce my timings. However, I did find an error in your first method: try In[134]:= f[17211, 1000] Out[134]= 17212000Bandit
It seems like a bug, but I guess it is a binary arithmetic problem. Floor@Log[10, 1000] yields 2. Chop fixes it.Evangelistic
@Mr.wizard No, Floor@Log[10, 1000] yields 3. It's the +1 you added that causes the problem for 1000. This doesn't look like a job for Chop.Bandit
@Sjoerd, pardon me, you misunderstand. Try: f[a_, b_] := b + a 10^Floor[1 + Log[10, b]]; f[17211, 1000] --- the math is right. Now try: Compile[{{b, _Integer}}, Floor@Log[10, b]][1000] --- it yields 2. ;-) You may be right about Chop.Evangelistic
ps. read "May be right about..." as "of course Chop doesn't do any good at all, what was I thinking!" ;-)Evangelistic
"The best minds make the best mistakes." Old Chinese proverb.Bandit

© 2022 - 2024 — McMap. All rights reserved.