Formatting numbers

We often need to display numbers, in GUI, text files or maybe the console window (Matlab Desktop). Matlab has built-in support for this using the fully-documented num2str, sprintf and format functions. Unfortunately, these built-in functions, useful as they are for simple needs, have several limitations:

They do not take into account the user’s computer Locale settings. For example, the number 1234.56 is normally displayed as 1,234.56 or 1’234.56 or 1234,56 depending on your chosen Locale (which is determined by the local language and country). The functions always use the same manner to display the number, disregarding the user’s Locale.

format does not enable customization of the number of decimal digits, and num2str and sprintf‘s ability to do so is limited. Customization of the decimal sign and thousands grouping sign is even more difficult.

I have recently completed a consulting work for a bank in Switzerland where these limitations were very important. The bank has branches in several countries and people naturally use different Locales on their computer. Moreover, some data values (for example, FOREX exchange rates) need more than two decimal digits. I had to find a generic cross-platform way to code this in Matlab in a way that will work for all users out-of-the-box (the application is compiled and distributed as an executable).

In the simple code snippet above, note the two alternative manners in which I set the DecimalFormat object’s properties, once with the set(‘XYZ’,value) function, then using the corresponding Java accessor method setXYZ(value). In most cases, we find that Java properties can be set using either of these manners, although using the Java accessor methods is typically safer and prevents some possible problems. Similarly, property values can be retrieved using either get(‘XYZ’) or the corresponding getXYZ() or isXYZ() Java methods (which are better).

Some of the interesting gettable/settable properties of the DecimalFormat object include (my Locale’s defaults are specified – your Locale might be different):

Currency – a java.util.Currency object that sets the currency symbol, international currency code and number of fractional decimal digits

DecimalFormatSymbols – a java.text.DecimalFormatSymbols object that sets the character symbols for such things as the decimal sign (“.” or “,” for example), grouping separator (“,” or ” ‘ ” or whatever), percent and per-mill signs, minus sign, infinity sign etc.

DecimalSeparatorAlwaysShown – (default=false) a boolean flag that specifies whether or not to display the decimal sign even for integer numbers. For example, “123.” rather than “123″.

GroupingSize – (default=3) indicates how many integer digits should be grouped by the grouping (“thousands”) separator sign.

GroupingUsed – (default=true) a boolean flag that specifies whether or not to use the grouping sign at all. Matlab’s built-in num2str does not use grouping.

MaximumFractionDigits – (default=3) the maximal number of digits to display to the right of the decimal sign. Post-rounding trailing zeros are omitted.

MinimumFractionDigits – (default=0) the minimum number of digits to display, padding with trailing zeros if necessary.

MaximumIntegerDigits – (default=intmax) the maximal number of digits to display to the left of the decimal sign. Extra digits are removed.

MinimumIntegerDigits – (default=1) the minimum number of digits to display, padding with leading zeros if necessary.

Multiplier – (default=1) multiplies the number by the specified value before converting to string.

NegativePrefix – (default=’-') the string to display to the left of a negative number.

NegativeSuffix – default = ”) the string to display to the right of a negative number. Some bankers like to display negative numbers as “(value)” and this is easy to do using NegativePrefix and NegativeSuffix. There are corresponding properties PositivePrefix and PositiveSuffix.

RoundingMode – (default=RoundingMode.HALF_EVEN) a java.math.RoundingMode object that sets the manner in which numbers are rounded to fit the required number of digits.

In addition, the DecimalFormat object provides methods that enable setting/getting a pattern that directly specifies how numbers should be parsed. A description of the different pattern components can be found here. The pattern directly corresponds to the settable properties listed above, and is very similar to the custom numeric pattern that is settable in Microsoft Excel. For example:

Alternatively, change the computer’s current Locale (in Windows, this is done via the Control Panel’s Regional Settings dialog), open a new Matlab session and rerun the code using the default DecimalFormat. Restarting Matlab is important, because the Locale is only read once by the Java engine (JVM), when it starts, and this happens when Matlab starts.

Window's Control Panel's Regional Settings Locale

To complete the picture, the DecimalFormat object can not only format a numeric value as a string, using format() as we have seen above, but also the reverse – convert a string to a numeric value using parse():

5 Responses to Formatting numbers

Do you have a solution to format doubles leaving n (say 4) significant digits for pos/neg numbers between for example [1e-5, 1e+5] and scientific notation for very large/small numbers like in example below?

Recent Comments

Christina (3 days 1 hour ago): In Matlab2007 I’m trying to use the JSlider but I keep getting a “Warning: Transform Fcn…” error every time the GUI repaints. I cannot find a way to get...

Ed Yu (3 days 2 hours ago): Yair, I would say with regard to loading classes through the java (root) classloader directly should not be that risky… As long as MATLAB is using Java, the root classloader...

sebastian (3 days 4 hours ago): Specifying relative paths in classpath.txt may not be supported, but for me it works just fine in R2011b. Simply add paths relative to the location of classpath.txt (i.e. relative...

Armindo (3 days 4 hours ago): Hi, I try to use the: function moveptr(hAx, x, y) However I get the following error Undefined function ‘getpos’ for input arguments of type ‘matlab.graphics.axis...

Martin (4 days 8 hours ago): @Mariam – you can also use the -struct flag of the save function, if you want to modify the struct s directly without going through another temporary variable: save('testFig.fig',...

Yair Altman (4 days 11 hours ago): @Mariam – the save command save the data including the variable name as top-level struct field. You should keep the same top-level field-name as used by the FIG format...

Mariam (4 days 15 hours ago): I tried it without making any changes to ‘s’. Just loading it s = load('C:\Users\Mariam\Desktop\ fitted response\atlas masks\IPS.fig','-mat'); and re-saving it...

mugurg (5 days 9 hours ago): If you want to use LaTeX interpreter of MATLAB, create .eps figures, and get the desired font (like Helvetica) instead of Computer Modern fonts, I think I’ve finally found a...

Yair Altman (5 days 11 hours ago): @Mariam – you can simply use the save command to save your modified d struct back into the *.fig file, and then open this FIG file normally: save('testFig.fig','d','-ma...

Mariam (5 days 13 hours ago): Hi, I have used above following command to load the attributes of figures d = load('testFig.fig','-mat') and then changed those attributes. I want to know how could I apply new...

Yaroslav (5 days 13 hours ago): So far, a smart solution is elusive; you can inspect Yair’s previous comment for a detailed analysis. In the meanwhile, you can try the old-school simple approach: N = 15;...

nasan (5 days 23 hours ago): Hi Yair, I’ve seen the demo but when I adapt it into my gui code gcbf is not recognize. How can I resolve it ? Can you give me a simply implementation in gui

Michael Cappello (8 days 4 hours ago): Yair (or anyone), I have an application where I need to color the bars individually, and have tried to figure out how to get the handles of the underlying patches or...