Formatting numbers for PRINT and DRAW TEXT statements

Henko
Posts: 822
Joined: Tue Apr 09, 2013 12:23 pm
My devices: iPhone,iPad
Windows
Location: Groningen, Netherlands
Flag: Netherlands

Formatting numbers for PRINT and DRAW TEXT statements

Post by Henko »

This is an update for my previous function (which did not survive a severe test by Dutchman :twisted: ).
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

Henko
Posts: 822
Joined: Tue Apr 09, 2013 12:23 pm
My devices: iPhone,iPad
Windows
Location: Groningen, Netherlands
Flag: Netherlands

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post 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


User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post by rbytes »

A very useful function. I like how it can be used to justify numbers left or right.

Thanks for posting! :D
The only thing that gets me down is gravity...

User avatar
Dutchman
Posts: 860
Joined: Mon May 06, 2013 9:21 am
My devices: iMac, iPad Air, iPhone
Location: Netherlands
Flag: Netherlands

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post by Dutchman »

I still can not use the function in 'European mode'
If I change th$ and dec$ in the function to

Code: Select all

th$="." ! dec$="," 'European mode
then I get the following result:
number formatting 2.PNG
number formatting 2.PNG (76.26 KiB) Viewed 7029 times

Henko
Posts: 822
Joined: Tue Apr 09, 2013 12:23 pm
My devices: iPhone,iPad
Windows
Location: Groningen, Netherlands
Flag: Netherlands

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post 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 :lol:

Henko
Posts: 822
Joined: Tue Apr 09, 2013 12:23 pm
My devices: iPhone,iPad
Windows
Location: Groningen, Netherlands
Flag: Netherlands

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post 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 :!: )

User avatar
Dutchman
Posts: 860
Joined: Mon May 06, 2013 9:21 am
My devices: iMac, iPad Air, iPhone
Location: Netherlands
Flag: Netherlands

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post 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
formatted output in European style.PNG (66.53 KiB) Viewed 7026 times
Last edited by Dutchman on Mon Feb 08, 2016 9:26 pm, edited 1 time in total.

User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post by rbytes »

Looks good. Is there a reason that it doesn't change the decimal characters in the right-hand column?
The only thing that gets me down is gravity...

User avatar
Dutchman
Posts: 860
Joined: Mon May 06, 2013 9:21 am
My devices: iMac, iPad Air, iPhone
Location: Netherlands
Flag: Netherlands

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post by Dutchman »

The right column is the standard 'PRINT number'-output

User avatar
GeorgeMcGinn
Posts: 435
Joined: Sat Sep 10, 2016 6:37 am
My devices: IPad Pro 10.5in
IMac
Linux i386
Windows 7 & 10
Location: Venice, FL
Flag: United States of America
Contact:

Re: Formatting numbers for PRINT and DRAW TEXT statements

Post 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 :!: )
George McGinn
Computer Scientist/Cosmologist/Writer/Photographer
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)

Post Reply