For the repeated pattern (number-dot-number-dot-number...) that substitution doesn't work because the number following the dot is
"consumed" and so the engine moved along the string, so the next character it sees is a dot, not the needed num-dot-num pattern.
One solution is to use lookarounds,† which are "zero-width" assertions, so with which the engine doesn't consume the match and doesn't move along, but it merely "looks" from its "spot" between characters to assert that the pattern (ahead or behind) matches, so to say
s/ (?<=[0-9]) \. (?=[0-9]) / @.@ /gx;
For a testable example (in Perl, as tagged)
perl -wE'$_=q(Dot. 1.2.3.4.5 Dot.); say; s/(?<=[0-9])\.(?=[0-9])/ @.@ /g; say'
which prints
Dot. 1.2.3.4.5 Dot.
Dot. 1 @.@ 2 @.@ 3 @.@ 4 @.@ 5 Dot.
But the lookbehind won't work with a "number" that consists of more than one digit, since then we'd need [0-9]+ which has variable and unlimited length, whiat lookbehinds can't (yet) do.
If it is indeed possible to have multi-digit numbers in your case, then the number before the . need be captured -- this still works with the number before the dot -- and then put back
s/([0-9]+)\.(?=[0-9])/$1 @.@ /g;
This can be done anyway, of course, even if it's all always single digits; i used lookbehind originally only for the symmetry with the other side (needing a lookahead)
† In a tool that supports them, which in my understanding sed isn't. (Thanks to comments by potong and Ed Morton for informing of that) I still offer this solution since Perl is one of the tagged languages.