Qbasicnews.com
May 21, 2022, 04:31:54 PM
 Pages: [1]
 Author Topic: STRING USING?  (Read 3858 times)
Antoni Gual
Na_th_an

Posts: 1434

 « on: February 03, 2005, 06:00:25 AM »

V1ctor:
I see you are implementing PRINT USING after saying in the first version yo would never do it. I understand you.. I once coded a PRINT USING as an external library for RapidQ. What a mess!

Could you add a STRING USING keyword, a sort of sprintf?
QBasic never had it, so I used a hack in Ethan Winer's book using the NUL: device and FIELD, but you reused FIELD, so you killed that hack...

STRING USING (or VB's FORMAT) would be useful to preformat things before sending them to GUI, not all output is to console or to file..
 Logged

Antoni
jdebord
Member

Posts: 60

 « Reply #1 on: February 03, 2005, 01:51:25 PM »

While I was testing the PRINT USING statement, I tried to write a function to convert floating point numbers to strings.

Here are some preliminary results:

Code:

FUNCTION DStr (X AS DOUBLE) AS STRING
' Alternative STR\$ function. Output is in fixed point format (no exponent).

IF X = 0 THEN DStr = " 0": EXIT FUNCTION

CONST InvLn10 = 0.43429448190325#  ' 1/ Ln(10)

DIM Y AS DOUBLE
DIM E AS INTEGER, D AS INTEGER, L AS INTEGER
DIM A AS STRING

Y = ABS(X)

' Get exponent
E = INT(LOG(Y) * InvLn10)

' Convert mantissa to string
A = LTRIM\$(STR\$(Y / 10 ^ E))

' Remove decimal point (if any)
IF INSTR(A, ".") > 0 THEN
A = LEFT\$(A, 1) + RIGHT\$(A, LEN(A) - 2)
END IF

IF E >= 0 THEN   ' Case |X| >=1

L = LEN(A)
D = E + 1      ' Position of decimal point

IF D > L THEN
A = A + STRING\$(D - L, "0")
ELSEIF D < L THEN
' Restore decimal point at its right place
A = LEFT\$(A, D) + "." + RIGHT\$(A, L - D)
END IF

ELSE             ' Case |X| < 1

IF E < -1 THEN A = STRING\$(-E - 1, "0") + A
A = "0." + A

END IF

' Add blank or negative sign
IF X >= 0 THEN A = " " + A ELSE A = "-" + A

DStr = A
END FUNCTION

FUNCTION FloatToStr (X AS DOUBLE, Ntot AS INTEGER, Ndec AS INTEGER) AS STRING
' Converts the floating point number X to a string
' Ntot = total length of string
' Ndec = number of decimal places

CONST MachEp = 2.22D-16

DIM P AS DOUBLE, Y AS DOUBLE
DIM D AS INTEGER, K AS INTEGER, L AS INTEGER
DIM S AS STRING, S1 AS STRING, S2 AS STRING

P = 10 ^ Ndec

Y = INT(ABS(X) * P + .5) / P  ' Round X to Ndec decimal places
Y = (1 + MachEp) * Y          ' Necessary to prevent negative roundoff error
IF X < 0 THEN Y = -Y

S = DStr(Y)

L = LEN(S)
K = INSTR(S, ".")

IF K > 0 THEN
D = L - K
IF D > Ndec THEN
' Remove unnecessary digits
S = LEFT\$(S, K - 1) + "." + MID\$(S, K + 1, Ndec)
ELSEIF D < Ndec THEN
S = S + STRING\$(Ndec - D, "0")
END IF
END IF

L = LEN(S)

' Remove decimal point if it's the last character
IF RIGHT\$(S, 1) = "." THEN S = LEFT\$(S, L - 1)

IF L < Ntot THEN S = SPACE\$(Ntot - L) + S

FloatToStr = S
END FUNCTION

Quite insufficient of course... But maybe a starting point ?

Jean Debord
 Logged

ean Debord
----------------
http://www.unilim.fr/pages_perso/jean.debord/tpmath/fbmath.zip
Antoni Gual
Na_th_an

Posts: 1434

 « Reply #2 on: February 03, 2005, 02:12:56 PM »

Thanks, Jean.

Perhaps I could also dig out my PRINT USING library for RapidQ  :
It would be of no use in FB, as it does'nt allow variable parameters lists. Speed has its constraints...EDITED: As a curiosity: it's here http://www.basicguru.com/rapidq/contrib/using.bas
END OF EDIT.

I'm asking v1ctor for STRING USING (or whatever syntax he prefers) because he's probably building PRINT USING's output on a string, and it would be easy to give the user access to that string, it's not a  brand new function to implement.
 Logged

Antoni
Jofers
Been there, done that

Posts: 1040

 « Reply #3 on: February 03, 2005, 02:16:06 PM »

Well, I guess you could go the veeery long way around it and trap the console output.
 Logged
 Pages: [1]