Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

TCL/TK format force width

Status
Not open for further replies.

Arnoshka

Technical User
Jul 10, 2009
17
DE
Hello,
I'm having big trouble finding a formating that fits my needs.

I have to create lists with numbers of maximum 8 characters.
Currently I'm using the "g" formatt,
Code:
return [format "%8g%8g%8g" $coordx $coordy $coordz]
but my variables "coordx", "coordy" und "coordz" are often close to zero null and in TCL this might give me a number like: 58.88178e-016.
Is there a possibility to force a number to a specific width??

Code:
0.123456 ->       0.123456
-0.123456 ->      -0.12345
58.88178e-016 ->  58.8e-16
-58.88178e-016 -> -58.e-16
4321.123456 ->    4321.123
...

thanks in advance
Arno

 
But %f doesn't force the number to a specific field width.

For my cause, the field width shall not exceed the length of eight characters.
 
Hi,
thank you for taking some time to respond.
The specific width is what I'm having trouble with.
like in my first note above the numbers are suposed to be with a maximum length of 8 characters

any number | formated number with max. eight characters
--------------------------
0.123456 -> | 0.123456
-0.123456 -> | -0.12345
58.88178e-016 -> | 58.8e-16
-58.88178e-016 ->| -58.e-16
4321.123456 -> | 4321.123
 
Hi,
thank you for taking some time to respond.
The specific width is what I'm having trouble with.
like in my first note above the numbers are suposed to be with a maximum length of 8 characters

any number | formated number with max. eight characters
--------------------------
0.123456 | 0.123456
-0.123456 | -0.12345
58.88178e-016 | 58.8e-16
-58.88178e-016 | -58.e-16
4321.123456 | 4321.123
 
%f can't handle that!
Code:
set coordx 4321.123456
puts [format "%8f" $coordx]

retuns
Code:
4321.123456
instead of
Code:
4321.123
 
With %f you can only specify the minimum fildwidth and the fixed amount of digits. But %f can't force the number to a specific width.
 
Hi Arnoshka,
As I wrote in the Fortran thread, where you posted your question first (I would first format the number with "%.5f".
But then some postprocessing is needed to adjust the number at 8 characters - if possible, e.g. something like this
Code:
[COLOR=#804040][b]proc[/b][/color] format_number {num} {
[COLOR=#0000ff]  # number with 5 decimal places[/color]
  [COLOR=#804040][b]set[/b][/color] num_dec5 [[COLOR=#804040][b]format[/b][/color] [COLOR=#ff00ff]"%.5f"[/color] [COLOR=#008080]$num[/color]]
[COLOR=#0000ff]  #puts "\$num_dec5 = $num_dec5"[/color]
  [COLOR=#804040][b]set[/b][/color] dec_point_pos [[COLOR=#804040][b]string[/b][/color] first [COLOR=#ff00ff]"."[/color] [COLOR=#008080]$num_dec5[/color]]
[COLOR=#0000ff]  #puts "\$dec_point_pos = $dec_point_pos"[/color]
[COLOR=#0000ff]  # number with length of 8 characters[/color]
  [COLOR=#804040][b]if[/b][/color] {[COLOR=#008080]$dec_point_pos[/color] < [COLOR=#ff00ff]7[/color]} {
    [COLOR=#804040][b]set[/b][/color] num_len8 [[COLOR=#804040][b]string[/b][/color] range [COLOR=#008080]$num_dec5[/color] [COLOR=#ff00ff]0[/color] [COLOR=#ff00ff]7[/color]]
    [COLOR=#804040][b]set[/b][/color] result [COLOR=#008080]$num_len8[/color]
  } [COLOR=#804040][b]elseif[/b][/color] {[COLOR=#008080]$dec_point_pos[/color] == [COLOR=#ff00ff]7[/color] || [COLOR=#008080]$dec_point_pos[/color] == [COLOR=#ff00ff]8[/color]} {
    [COLOR=#804040][b]set[/b][/color] num_len8 [[COLOR=#804040][b]string[/b][/color] range [COLOR=#008080]$num_dec5[/color] [COLOR=#ff00ff]0[/color] [COLOR=#008080]$dec_point_pos[/color]-[COLOR=#ff00ff]1[/color]]
    [COLOR=#804040][b]set[/b][/color] result [COLOR=#008080]$num_len8[/color]
  } [COLOR=#804040][b]else[/b][/color] {
    [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"Number could not be formatted at 8 characters !"[/color]
    [COLOR=#804040][b]set[/b][/color] result [COLOR=#008080]$num[/color]
  }
[COLOR=#0000ff]  #puts "\$result = $result"[/color]
  [COLOR=#804040][b]return[/b][/color] [COLOR=#008080]$result[/color]
}

[COLOR=#0000ff]# *** main ***[/color]
[COLOR=#804040][b]set[/b][/color] num_list [[COLOR=#804040][b]list[/b][/color] [COLOR=#ff00ff]0.123456[/color] -[COLOR=#ff00ff]0.123456[/color] [COLOR=#ff00ff]58.88178e-016[/color] -[COLOR=#ff00ff]58.88178e-016[/color] [COLOR=#ff0000]\[/color]
[COLOR=#ff00ff]1[/color] [COLOR=#ff00ff]30[/color] [COLOR=#ff00ff]40000[/color] [COLOR=#ff00ff]4321.123456[/color] [COLOR=#ff00ff]1234567.1234567[/color] -[COLOR=#ff00ff]1234567.1234567[/color] [COLOR=#ff0000]\[/color]
[COLOR=#ff00ff]12345678.1234567[/color] -[COLOR=#ff00ff]12345678.1234567[/color] [COLOR=#ff00ff]123456789.12[/color]]

[COLOR=#804040][b]foreach[/b][/color] num [COLOR=#008080]$num_list[/color] {
  [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"[/color][COLOR=#6a5acd]\$[/color][COLOR=#ff00ff]num     = $num"[/color]
  [COLOR=#804040][b]set[/b][/color] num_fmt [format_number [COLOR=#008080]$num[/color]]
  [COLOR=#804040][b]puts[/b][/color] [COLOR=#ff00ff]"[/color][COLOR=#6a5acd]\$[/color][COLOR=#ff00ff]num_fmt = $num_fmt"[/color]
  [COLOR=#804040][b]puts[/b][/color] {}
}
Output:
Code:
$num     = 0.123456
$num_fmt = 0.12346

$num     = -0.123456
$num_fmt = -0.12346

$num     = 58.88178e-016
$num_fmt = 0.00000

$num     = -58.88178e-016
$num_fmt = -0.00000

$num     = 1
$num_fmt = 1.00000

$num     = 30
$num_fmt = 30.00000

$num     = 40000
$num_fmt = 40000.00

$num     = 4321.123456
$num_fmt = 4321.123

$num     = 1234567.1234567
$num_fmt = 1234567

$num     = -1234567.1234567
$num_fmt = -1234567

$num     = 12345678.1234567
$num_fmt = 12345678

$num     = -12345678.1234567
Number could not be formatted at 8 characters !
$num_fmt = -12345678.1234567

$num     = 123456789.12
Number could not be formatted at 8 characters !
$num_fmt = 123456789.12
 
WOW
I guess this will suit my needs. surprising that TCL doesn't come with formating comands to solve this problem.
As far as I know fortran does.

Still big numbers are not transformt into a short exponential writing.
But for most cases it'll prevent errors to occure due to very small numerical offsets from zero.

It didn't seam as if others would understand what the question actually means.
Thank you very much. I hope my calculatins are having less errors now.

Kind regards
Arno
 
...surprising that TCL doesn't come with formating comands to solve this problem
And what language comes with such a command which fulfil exactly your needs?
:)
...Still big numbers are not transformt into a short exponential writing.
You cannot format numbers with more then 8 digits before decimal point at 8 character length.
I looked at the exponential notation too:
for the number
$num = 123456789.12
with this format
Code:
set num_fmt [format "%e" $num]
we get this
$num_fmt = 1.234568e+008
Because 1.234568 * 10**8 = 123456800, so we get the difference from original |123456800 - 123456789.12| = 10.88
This difference seems to be big. On the other side, 10 in relation to 10**8 is not big.

 
Hi,
thats true which language does...
By the way, I just noticed, there is still one thing knocking me out.
Currently I am programming an interface for a analysis program. In my case I have to return the complete string with the correct format.
I used your code just the way you wrote it.
and inserted a vew things.

Code:
set i 0
foreach num $num_list {
	incr i
  set num_fmt [format_number $num]
  		set coord$i  $num_fmt
}
giving me the thre numbers coord1 coord2 and coord3
I'm having two options connecting the three coordinates for one single return.

Code:
return [format "% f% f% f" $coord1 $coord2 $coord3]
(I inserted the space to insert space when the number is not signt.) But the numbres displayed are getting a Zero at the end. So I end up having nine characters all the time.
if I insert the exact string I can't use the option to insert space if the string is not signed
Code:
return[format "% s% s% s" $coord1 $coord2 $coord3]
so currently i end up havig either
with %f
8 characters when positive
9 characters when negative

with % f
9 characters for both positive and negative

with %s
7 characters when positive
8 characters when negative

hmm..
 
ok i found the solution. After all of the operations from above the output has to be like:
Code:
return[format "% 8s% 8s% 8s" $coord1 $coord2 $coord3]
Thank you again for your help.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top