# Scientific notation for exact numbers?

Some of my symbolic computations involve many large numbers, e.g.:

37894580188800000000000000000000000000000000000000

As the computation is symbolic, I'd like to leave the numbers in exact form, holding off the numerical conversion until the end.

This, however, makes the presentation of intermediate results unwieldy (especially if the expression contains a lot of large numbers). It would be nice if there were a function that caused an output to display all its over-threshold exact numbers in scientific notation, while keeping them exact internally. For instance in the case of the above, it would be:

3.78945801888 x 10^49

Wolfram's documentation says "The Wolfram Language provides flexible mechanisms for full typeset formatting of numbers of any magnitude and precision", but I've not been able to find a function that does this.

EDIT: Thanks kglr and Carl! Here's how your functions work on one of my test cases (too long to put into the comments):

test = (BesselJ[-(3/4), (307792869430417000000000000000000 Mrest)/
56948374077008069066071] BesselY[-(1/4), (
307792869430417000000000000000000 Mrest)/
56948374077008069066071] +
BesselJ[3/4, (307792869430417000000000000000000 Mrest)/
56948374077008069066071] BesselY[1/4, (
307792869430417000000000000000000 Mrest)/
56948374077008069066071]) (Quantity[-((
2053373 Sqrt[73/18913] Mrest^3 \[Pi]^(3/2))/
218400036542934750122025461419177208453231459616518446904000000000\
00), 1/("Kilograms")^3])


kglr (these approaches give nice compactness, and have the convenience of only needing to be applied once) (the results from the two are identical):

$$Post = N test$$Post=.
(*OR*)
$$PrePrint = If[Precision[#] == \[Infinity], N[#], N[#, Precision[#]]] &; test$$PrePrint =.


Carl (this function is useful if I want to keep track of the individual numbers):

inexactForm[test]


• maybe $Post = N? (see$Post)
– kglr
Dec 30, 2019 at 23:39
• Dec 31, 2019 at 8:13

You can try $Post or $PrePrint:

### $Post num = 37894580188800000000000000000000000000000000000000;$Post = N; (* apply N to every output expression *)

num


3.78945801888*^49

Precision[num]


Reset

$Post = . num  37894580188800000000000000000000000000000000000000 ### $PrePrint

Apply N to every expression before it is printed -- "Show exact quantities by their numerical value:"

$PrePrint = Replace[#, x_?NumericQ :> If[Precision[x] == ∞, N[x], N[x, Precision[x]]], All] &; num foo[{num, bar[1020], 22}]  • I like this (+1) but I think you will want to make the $PrePrint example more general, so that it applies all formats of output; as written the output must be a bare Integer. Dec 31, 2019 at 0:47
• @Mr.Wizard, thank you for the upvote. Added another example.
– kglr
Dec 31, 2019 at 2:10
• $Post = N is a simple, elegant solution. It would be nice if it left the Bessel orders as exacts, but I'm basically happy with it. Dec 31, 2019 at 3:16 • Perhaps I wasn't clear. Consider {num, 1020} and {num, 1020, 22} for example; shouldn't these give something like {3.78946*10^49, 10.000000000000000000, 2.0} instead? Dec 31, 2019 at 6:30 • Yes, I understand that -- that's why I was surprised you were showing a backtick as appearing in an Output cell (designated in yellow in your answer). When I copied the output of your code into the addendum to my question, I don't get a backtick (and I also don't get the same no. of displayed digits). I believe what's going on is that you copied the output of your \$PrePrint code directly into your MSE post (as I did)--but, rather than doing the same for the output of your \\$Post code, you first copied its output into an Input cell, and then copied from the Input cell into your post. Dec 31, 2019 at 21:32

You can create wrapper function to do this:

MakeBoxes[inexactForm[e_], StandardForm] ^:= InternalInheritedBlock[{Integer},
Unprotect[Integer];
MakeBoxes[i_Integer, StandardForm] ^:= With[{n=N@i}, MakeBoxes[n, StandardForm]];
MakeBoxes[e, StandardForm]
]


Then:

inexactForm[
a[
37894580188800000000000000000000000000000000000000,
37894580188800000000000000000000000000000000000000
]
]


a[3.78946*10^49,3.78946*10^49]

You could just modify the display Format of specific functions/patterns:

Unprotect[BesselJ, BesselY];
Format[BesselJ[n_, z_ /; Precision[z] == ∞]] := BesselJ[n, N[z]]
Format[BesselY[n_, z_ /; Precision[z] == ∞]] := BesselY[n, N[z]]
Protect[BesselJ, BesselY];


then we get a more legible display without modifying any variables:

test

(*    (BesselJ[-(3/4), 5.40477*10^9 Mrest] BesselY[-(1/4), 5.40477*10^9 Mrest] +
BesselJ[3/4, 5.40477*10^9 Mrest] BesselY[1/4, 5.40477*10^9 Mrest]) (Quantity[...])    *)

• Consider MakeBoxes; no need to Unprotect and you can combine definitions: MakeBoxes[(h : BesselJ | BesselY)[n_, z_ /; Precision[z] == ∞], fmt_] := ToBoxes @ h[n, N[z]]` Jan 1, 2020 at 5:15
• @Mr.Wizard yes that's a possibility. I try to keep my code agnostic about boxes, seeing them as a low-level mechanism that may not age well. Jan 1, 2020 at 9:02