# Control the number of digits in CForm output?

GROUPS:
 I would like to print out numbers in C form with exactly 3 digits after the decimal point. E.g. 1.23456*^8 -> 1.234e8 1.0*^8 -> 1.000e8 I thought I could do something like PaddedForm[CForm[1.23456*^8],{8,3}] but that didn't work. CForm[SetPrecision[1.0*^8 ,4]] also fails to give 3 digits after the decimal point.
7 months ago
4 Replies
 Neil Singer 2 Votes Mark,This is actually very hard -- there is no simple way to do it. I posted a similar question here in my post but got no replies and even had tech support look at it and had little resolution. I came up with an approach that works by wrapping the numbers in a temporary function and after turning everything into CForm, doing a string replace. Here is some sample code. mapReplace goes through an expression and replaces the Real numbers with a dummy function acf[ paddedform ]. You can edit the paddedForm below to get your desired format. mapReplace[exp_] := MapAt[acf[ ToString[ PaddedForm[#, {8, 3}, NumberFormat -> (Row[{#1, If[#3 != "", "e", ""], #3}] &)]]] &, exp, Position[exp, _Real]] after this you do a stringReplace to clean it all up: CNumberReformat[expr_] := StringReplace[ ToString[mapReplace[expr], CForm], Shortest["acf(\"" ~~ x__ ~~ "\")"] :> "(" <> x <> ")"] To use it: equation = 25.32032 - 4.55 x + 16.0006 z + 2 y + 234.2341*^8 CNumberReformat[equation] to get 2y + z( 16.001) + ( 2.342e10) + x*( -4.550) I hope this helps.
 Thank you for your suggestion. What I was really hoping for was something like the C/Python "%e" format, that always produces a string of the same length, so it could be used, for example, to print data in nicely aligned columns:  1.000e12 -1.000e9 1.000e3 -1.000e1 1.000e0 -1.000e-1 If I understand it correctly, your proposal for an individual number would be something like CFormat[x_,n_,f_]:= ToString[ PaddedForm[x, {n, f}, NumberFormat -> (Row[{#1, If[#3 != "", "e", ""], #3}] &) ] ] but that doesn't create strings of a fixed length, e,g, "<" <> CFormat[1.0*^6,9,3] <> ">" < 1.000e6> "<" <> CFormat[10,9,3] <> ">" < 10.000> I still don't understand how PaddedForm works. In the example above, the "9" that gets passed to PaddedForm doesn't cause it to produce a string of length 9: the actual output is much longer.
 Neil Singer 1 Vote If you define the format function as follows: format[x_] := ToString[PaddedForm[x, {4, 3}, NumberFormat -> (Row[{#1, If[#3 != "", "e", ""], #3}] &), ExponentFunction -> (# &)]] It will do the formatting you want. I added the ExponentFunction option. By always returning its argument (#,&), you ALWAYS get exponential notation. (If you want to limit exponential notation to a range of exponents, you can change the function -- see the documentation examples). You can add this format to what I posted above by doing this: mapReplace[exp_] := MapAt[acf[format[#]] &, exp, Position[exp, _Real]] You can get almost any formatting you want this way but it requires studying the PaddedForm options carefully.If you really want C formatting, you can very easily call a C sprintf external and print your numbers (and use the code I posted above to apply it to all the numbers in your equations). I have done this in the past (for similar reasons) and I post my code here so you can use it. See the .nb file for instructions. You will need the c file (I had to use a .txt extension to be able to post it). and a .tm file (same name change required). The command I put in the notebook is for a Mac but you can do the same on the PC by looking at the WSTP documentation (for Mac) (for windows).Using this external function you will get the full functionality of C sprintf for formatting a single number. If you want a more general sprintf function you can edit my C code and tm file to get what you need. I hope this helps. Attachments: