uFormat$() and StrE$() provide flexible formatting of numeric values

Modified on 2018/12/14 13:07 by Administrator — Categorized as: Control, Encode and Decode, Environment, Maths

Some languages provide the FORMAT$() function - indeed this features in MMBasic for the MaxiMite but has been dropped from versions intended for the MicroMite (V4.5 onward). It can be an intensive function for some often quite fringe functions. A fully fledged version is documented here. I think you'll agree it is a lot of work for often little payback... fine on PC's with multi-gigabyte memories but not really worth the flash in confined systems when the function is rarely used.

In MMBasic, the STR$() function does provide a lot of the numerical formatting but still misses a couple of types aimed specifically at engineering tasks.

Below are two functions that provide the most common formatting options for decimal numbers, allowing numeric values to be returned (as a string) correctly formatted. Both functions are reproduced here courtesy of The Back Shed user; TassyJim and the original threads can be found here and here.


uFormat$()
This function formats a value to the nearest number of decimal places required. It will round the number up or down to do this i.e. if you ask for the value 5900 rounded to the nearest thousand (negative option) the returned value will be 6000 and so on.

Example Code
	For p = -3 TO 3
		Print uFormat$(6258.990876,p)
	Next p

The output illustrates the action of the formatting option:

6000
6300
6260
6259
6259.0
6258.99
6258.991



Dependencies
None.

' The function
	Function uFormat$(x,p)
		' given a number (x) and the required number of decimal places (p)
		' returns formatted string. Negative and zero p is permitted
		Local f$
		f$=Str$(Cint(x*10^p))
		If Len(f$)<=p Then
			f$=String$(p+1-Len(f$), "0")+f$
		EndIf
		If p>0 Then
			uFormat$=Left$(f$,Len(f$)-p)+"."+Right$(f$,p)
		ElseIf p = 0 Then
			uFormat$=f$
		Else
			uFormat$=f$+String$(Abs(p),"0")
		EndIf
	End Function



StrE$()
Is an enhanced form of the STR$() function that returns a numeric value using scientific/engineering notation - that is a value and exponent. Engineering notation groups number by thousands e.g. 100,000 will be returned as 100e+3 whereas in scientific notation, the same value would be return as 1e+5, always reducing the value to between 0 and 9.9999»

Example Code

	q=.000001
		Print StrE$(q,1,1),,StrE$(q,5,0)
	q=.0001
		Print StrE$(q,2,1),,StrE$(q,5,0)
	q=.01
		Print StrE$(q,3,1),,StrE$(q,5,0)
	q=.455
		Print StrE$(q,4,1),,StrE$(q,5,0)
	q=0
		Print StrE$(q,4,1),,StrE$(q,5,0)
	q=1
		Print StrE$(q,5,1),,StrE$(q,5,0)
	q=7748
		Print StrE$(q,6,1),,StrE$(q,5,-1)
	q=100000
		Print StrE$(q,7,1),,StrE$(q,5,-1)
	q=2200000
		Print StrE$(q,8,1),,StrE$(q,5,0)

Again, the output illustrates the action of the formatting options (note also how the formatting can expose the limitations of single precision Floating Point maths):

1.0e-6 1.00000e-6
100.00e-6 1.00000e-4
10.000e-3 1.00000e-2
455.0000e-3 4.55000e-1
0.0000 0.00000
1.00000e0 1.00000e0
7.748000e3 7.74800e3
99.9999923e3 100.00000e3
2.20000004e6 2.20000e6


Dependencies
None.


' the function
	Function strE$(mx,p,eng)
		' mx = number to format
		' p = number of decimal places
		' if eng is not zero, use engineering notation 
		Local sn$
		Local Float x,px
		sn$=" "
		x=mx
		If x<0 Then
			sn$="-"
			x=x*-1
		EndIf
		If x<>0 Then  ' zero is a special case
			px=Int(Log(x)/Log(10))
			If eng<>0 Then ' engineering notation - multiples of 3
				px=Int(px/3)*3
			EndIf
			x=x*(10^-px)
			strE$=sn$+Str$(x,0,p)+"e"
			' if Sgn(Int(px))<>-1 Then strE$=strE$+"+"  ' un-REM this line to force the exponent sign e.g. 1e+6 instead of 1e6
			strE$=stre$+Str$(Int(px))
		Else
			strE$=sn$+Str$(x,0,P)
		EndIf
	End Function