One can use $PrePrint
and ReplaceAll
to effect this:
$PrePrint = # /. {
Log[n_]/Log[2] :> Defer @ Log2[n],
Log[n_]/Log[10] :> Defer @ Log10[n],
Log[n_]/Log[b_] :> Defer @ Log[b, n]
} &;
Or MakeBoxes
:
MakeBoxes[Log[n_]/Log[2], fmt_] := ToBoxes[Defer @ Log2[n], fmt]
MakeBoxes[Log[n_]/Log[10], fmt_] := ToBoxes[Defer @ Log10[n], fmt]
MakeBoxes[Log[n_]/Log[b_], fmt_] := ToBoxes[Defer @ Log[b, n], fmt]
It is also possible to use Format
but in this case it requires unprotecting Times
:
Unprotect[Times];
Format[Log[n_]/Log[2]] := Defer @ Log2[n]
Format[Log[n_]/Log[10]] := Defer @ Log10[n]
Format[Log[n_]/Log[b_]] := Defer @ Log[b, n]
Protect[Times];
These assignments are made to a special class of rules: FormatValues
. Because these are only used in formatting this should not slow down internal operations using Times
, unlike overloading UpValues
or DownValues
.
Each method relies on Defer
to prevent an infinite recursion yet allow evaluation of output when it is given as input.
Result:

Log10[2] + Log[5]
automatically converts to1/Log2[10] + Log2[5]/Log2[E]
if you're a CS person? $\endgroup$Log[17]/Log[2]
is a problem I actually face: seeing that kind of output annoys me as I compulsively want to shorten it. :^) $\endgroup$