Page 1 of 3
Formatting numbers for PRINT and DRAW TEXT statements
Posted: Sat Feb 06, 2016 1:43 pm
by Henko
This is an update for my previous function (which did not survive a severe test by Dutchman

).
The total field length may be entered, or calculated (read comments) and the number of decimal positions. Thousands are separated
Code: Select all
' testprogram for n2a$() function
'
for i=1 to 9 ! read num(i) ! next i
data 87643210.23
data 6.432123E+4
data 0.00123456
data 12345678.123456
data -12345678.12
data 2000
data 13.5E+8
data -.003678E+1
data 13.5E-9
for i=1 to 8
print n2a$(num(i),0,4)&" ";num(i)
next i
print
for i=1 to 8
print n2a$(num(i),20,4)&" ";num(i)
next i
end
' format a number for PRINT or DRAW TEXT statement
' num = the number to be formatted
' len = the field length to be used for the formatted number,
' inclusive decimals, sign, dots, and comma
' len=0 will automatically use the shortest field needed
' dec = the number of decimal positions
' to print a table right-aligned, give len a value of at least the
' longest number in the table. Giving even more than that, will
' have a TAB effect for the whole table
'
def n2a$(num,len,dec)
fs$=" " ! fh$="################" ! s=0
th$="," ! dec$="." ' uk/us tokens for thousands and decimal
if num<0 then ! s=1 ! num=-num ! else ! s=0 ! end if
ent=floor(num) ! frac=fract(num) ! spaces=0
pre=max(floor(log10(num)+1),1) ! noc=floor((pre-1)/3)
le=pre+noc+s ! if dec then le+=dec+1
if len and len>le then spaces=len-le
if spaces then format$=left$(fs$,spaces) else format$=""
if s then format$ &= "-"
format$ &= left$(fh$,pre-3*noc)
if noc then
for i=1 to noc ! format$ &= th$ & "###" ! next i
end if
if dec then format$ &= dec$ & left$(fh$,dec)
return str$(num,format$)
end def
Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Sun Feb 07, 2016 8:20 am
by Henko
Final version (removed limitations on field length and number of decimals)
Code: Select all
' testprogram for n2a$() function
'
for i=1 to 9 ! read num(i) ! next i
data 87643210.23
data 6.432123E+4
data 0.00123456
data 12345678.123456
data -12345678.12
data 2000
data 13.5E+8
data -.003678E+1
data .123456
print
for i=1 to 9
print n2a$(num(i),20,2)&" ";num(i)
next i
end
' format a number for PRINT or DRAW TEXT statement
' num = the number to be formatted
' len = the field length to be used for the formatted number,
' inclusive decimals, sign, dots, and comma
' len=0 will automatically use the shortest field needed
' dec = the number of decimal positions
' to print a table right-aligned, give len a value of at least the
' longest number in the table. Giving even more than that, will
' have a TAB effect for the whole table
'
def n2a$(num,len,dec)
dec=max(dec,0)! fh$="###" ! f$="" ! th$="," ! dec$="."
if num<0 then ! s=1 ! num=-num ! else ! s=0 ! end if
ent=floor(num) ! frac=fract(num) ! spaces=0
pre=max(floor(log10(num)+1),1) ! noc=floor((pre-1)/3)
le=pre+noc+s ! if dec then le+=dec+1
if len and len>le then spaces=len-le
while spaces ! f$&=" " ! spaces-=1 ! end while
if s then f$ &= "-" ! f$&=left$(fh$,pre-3*noc)
while noc ! f$&=th$&fh$ ! noc-=1 ! end while
if dec then ! f$&=dec$ ! while dec ! f$&="#" ! dec-=1 ! end while ! end if
return str$(num,f$)
end def
Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Sun Feb 07, 2016 3:29 pm
by rbytes
A very useful function. I like how it can be used to justify numbers left or right.
Thanks for posting!

Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Mon Feb 08, 2016 3:43 pm
by Dutchman
I still can not use the function in 'European mode'
If I change th$ and dec$ in the function to
then I get the following result:

- number formatting 2.PNG (76.26 KiB) Viewed 7051 times
Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Mon Feb 08, 2016 4:04 pm
by Henko
I know, I did the same test and got the same weird results. I guess it is the way the formatstring mechanism operates in SB (or in iOS for that matter).
If that's the case, then i guess the SB formatstring should not be used and a more basic method should be used. But the present function operates well enough for me. I will take the weird anglo-saxon habits for granted

Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Mon Feb 08, 2016 4:10 pm
by Henko
The 'ent' and 'frac' variables are still a remnant of a more basic approach. These variables are not used now and might be deleted (the remaining 'spaces=0' instruction on the same line can be moves to the IF statement further on as an ELSE clause, thus reducing the number of coding lines by one

)
Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Mon Feb 08, 2016 9:19 pm
by Dutchman
I have made a formatting function in which the decimal separator and the grouping separator can and should be set.
Code: Select all
'Formatting numbers for PRINT and DRAW TEXT statements
'by Dutchman, febr 2016
'
'Testprogram
format$.dec$="," ! format$.sep$="." 'European style
FOR i=1 to 9 ! read num(i)
PRINT format$(num(i),20,2)&" ";num(i)
NEXT i
end
data 876543210.23
data 6.432123E+4
data 0.00123456
data 12345678.123456
data -12345678.12
data 2000
data 13.5E+8
data -.003678E+1
data .123456
' format a number for PRINT or DRAW TEXT statement
' the function should be initiated by setting the
' decimal separator 'format$.dec$'
' and optionally the grouping separator 'format$.sep$'
' num = the number to be formatted
' wid = the field length to be used for the formatted number,
' inclusive decimals, sign, dots, comma's and spaces
' len=0 will automatically use the shortest field needed
' dec = the number of decimal positions
' to print a table right-aligned, give len a value of at least the
' longest number in the table.
' if the number is too long, then the grouping will not be complete
'
DEF format$(num,wid,dec)
IF dec$="" THEN error
base=OPTION_BASE() 'save base
OPTION BASE 1
neg=0 ! IF num<0 THEN ! neg=1 ! num=-num ! ENDIF
'make formatstring of total length
n$="" ! f$="" ! FOR i=1 TO wid ! f$&="#" ! NEXT i
'add decimal point
f$=MID$(f$,wid-dec,1,".")
IF sep$="" THEN GOTO format
'add blank spacing
pos=wid-dec-4
WHILE pos>0 ! f$=MID$(f$,pos,1," ") ! pos-=4 ! END WHILE
format: 'use format command
n$=STR$(num,f$)
IF sep$="" THEN GOTO sign
'change separator
pos=LEN(n$)-dec-4
WHILE pos>1 AND MID$(n$,pos,1)=" " AND MID$(n$,pos-1,1)<>" "
n$=MID$(n$,pos,1,sep$) ! pos-=4
END WHILE
IF NOT neg THEN GOTO exit
sign: 'correct sign
pos=0 ! DO ! pos+=1 ! UNTIL MID$(n$,pos,1)<>" "
if pos>1 THEN ! n$=MID$(n$,pos-1,1,"-")
ELSE ! n$="-"&n$ ! ENDIF
exit:
'change decimal separator
n$=MID$(n$,LEN(n$)-dec,1,dec$)
OPTION BASE base 'restore base
RETURN n$
error:
TEXT ! TEXT CLEAR
PRINT "variable 'dec$' and optionally 'sep$' should be set in format$ function"
STOP
END DEF
It gives the desired output as shown in the following screenshot.

- formatted output in European style.PNG (66.53 KiB) Viewed 7048 times
Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Mon Feb 08, 2016 9:22 pm
by rbytes
Looks good. Is there a reason that it doesn't change the decimal characters in the right-hand column?
Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Mon Feb 08, 2016 9:25 pm
by Dutchman
The right column is the standard 'PRINT number'-output
Re: Formatting numbers for PRINT and DRAW TEXT statements
Posted: Mon Nov 07, 2016 1:35 am
by GeorgeMcGinn
I hope not (at least for FRACT) as there are many programs in astronomy and cosmology written in BASIC that use it.
My method for formatting numbers uses no loops at all! (I'm from the old school of computer scientists who view loops, no matter how small, are drains on CPU resources). A small loop executed 1,000 times will effect all other programs running on a mainframe, or interfere with a supercomputer's (PC/MAC/Server, etc) operating system. It can lock out everything else while it satisfies to looping.
That's why these math functions are so important. It is more efficient to do this in assembler, which most are written, than done is intrepreted code or 4th generation languages like COBOL. The assembler code generated from those old compilers are a mess and no where near as efficient as a properly written function in assembler.
I guess in event-driven processing, like windows applications and APPS it doesn't have much of an impact.
My two-cents!
George.
Henko wrote:The 'ent' and 'frac' variables are still a remnant of a more basic approach. These variables are not used now and might be deleted (the remaining 'spaces=0' instruction on the same line can be moves to the IF statement further on as an ELSE clause, thus reducing the number of coding lines by one

)