Version 2 of Floating-point formatting

Updated 2003-02-12 10:07:11

Arjen Markus (11 february 2003) I had a question from a customer about numbers that were displayed with too many digits, like "28.000" instead of "28.0". So, this raised the question: what can we do to make the appearance of (floating-point) numbers more elegant?

As it turns out, the format command has a lot of options, one of them is the # attribute to %g. Now, if all you have is the textual description of the effects, you will be very puzzled indeed.

So, here is a little script that examines the effects:

   # Check the effects of the various formats for floating-point numbers
   #
   foreach value {1.0 -1.0 1.01 -1.01 0.00001 -0.00001 1000000.0 -1000000.0} {
      set result ""
      foreach form {%g %-g %6g %6.4g %#.4g %06g %-6g} {
         append result [format " >$form<" $value]
      }
    puts "Value $value: $result"
   }

I have reformatted the output a bit, to get the following table:

  Formats:           %g       %-g       %6g       %6.4g     %#.4g        %06g   %-6g
  Value 1.0:         >1<      >1<       >     1<  >     1<  >1.000<      >000001< >1     <
  Value -1.0:        >-1<     >-1<      >    -1<  >    -1<  >-1.000<     >-00001< >-1     <
  Value 1.01:        >1.01<   >1.01<    >  1.01<  >  1.01<  >1.010<      >001.01< >1.01  <
  Value -1.01:       >-1.01<  >-1.01<   > -1.01<  > -1.01<  >-1.010<     >-01.01< >-1.01 <
  Value 0.00001:     >1e-05<  >1e-05<   > 1e-05<  > 1e-05<  >1.000e-05<  >01e-05< >1e-05 <
  Value -0.00001:    >-1e-05< >-1e-05<  >-1e-05<  >-1e-05<  >-1.000e-05< >-1e-05< >-1e-05<
  Value 1000000.0:   >1e+06<  >1e+06<   > 1e+06<  > 1e+06<  >1.000e+06<  >01e+06< >1e-06 <
  Value -1000000.0:  >-1e+06< >-1e+06<  >-1e+06<  >-1e+06<  >-1.000e+06< >-1e+06< >-1e+06<

However, there's more! The full format specification is huge and very, very complex. Here it is, bit by bit, aimed at people doing float formatting...

  • Start with a % symbol.
  • Add any optional positional specifier:
  1. If you don't want to use the next value off the argument list, add argListIndex and $ here. This is mainly useful for localized formats.
  • Add any optional flags:
  1. If you are going to make the space taken up by the field (potentially) larger than required to always hold the value and you want the field left-justified, add a - here.
  2. If you always want a sign, add a + here.
  3. If you want a space when the number isn't negative, add a space character here. Don't mix with the +.
  4. If you want to pad out with zeroes, not spaces, add a 0 here.
  5. If you want to use the alternate form, add a # here. This guarantees you get a decimal point and, for the g conversion guarantees you a full set of zeroes after the decimal point.
  • Add any optional field width:
  1. If you want to specify a minimum field width (as used in many of the examples above) put the (decimal) width of the field here. You can also take this value as an argument to [format] using a * instead.
  • Add any optional precision in either the form .number or .* (the latter if you want to take the value as an argument to [format], as with the field width above):
  1. If you are using the g conversion, you can say the maximum total number of digits to appear (excluding the exponent)
  2. If you are using the e or f conversions, you can say the number of digits to appear after the decimal point.
  • Floats don't use length modifiers in Tcl. They're only used for integer values.
  • Finally, add the conversion specifier which marks the end of the format.
  1. f uses normal notation.
  2. e uses scientific notation.
  3. E is just like e but uses a capital letter for the exponent char.
  4. g uses either normal or scientific notation, depending on the scale of the number.
  5. G is just like g but uses a capital letter for the exponent char (if printed).

[ Arts and crafts of Tcl-Tk programming ]