Printing leading zeroes
#1
I'm sure at some point I've done this, but now I can't find the example.

Let's say I'm wanting to express a heading to navigate. Formally, instead of saying "heading 45," you would say "heading 045 degrees."

So, if I calculate a heading of 45, how would I then print that as 045? In hex, you'd use

c$ = Right$("0000" + Hex$(n), 4)

to always show leading 0s if the hex value otherwise might consist of less than four characters. I'm pretty sure there's a way of doing this sort of thing directly with decimal numbers?

Thanks, guys. I couldn't figure out where to find this in the wiki.
Reply
#2
This is what I've designed and used for a long time:

Code: (Select All)
'this allows a negative value padded by zeroes after sign
'set "numdig" to negative value to convert "num" to hexadecimal
'eg. "numdig = -6" to convert "num" to 6-digit hexadecimal string
FUNCTION Zeroes$ (num AS LONG, numdig AS INTEGER)
DIM b$, hx AS LONG, sg AS LONG, v AS LONG
IF num < 0 THEN sg = -1: num = num * -1
IF numdig < 0 THEN hx = 1: numdig = numdig * -1 ELSE hx = 0
IF hx THEN
    b$ = HEX$(num)
ELSE
    b$ = LTRIM$(STR$(num))
END IF
v = numdig - LEN(b$)
IF v > 0 THEN b$ = STRING$(v, 48) + b$
IF sg = -1 THEN b$ = "-" + b$
Zeroes$ = b$
END FUNCTION

Call:

Code: (Select All)
DIM a$, nl AS LONG
nl = 99999
a$ = Zeroes$(nl, -6)

"a$" then should give you a hexadecimal number of six digits padded by zeroes. "01869F", if you need the "&H" before it you will have to concatenate it separately.

Otherwise the second parameter should be greater than zero, for the number of digits you want in front of a decimal number.
Reply
#3
Almost the same as what you posted:
Code: (Select All)
c$ = Right$("0000" + Ltrim$(Str$((n)), 4)
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#4
I use something like this:

Code: (Select All)
Print PaddedString(0.1, 2, 5)
Print PaddedString(3, 0, 2)
Print PaddedString(3, 2, 5)




Function PaddedString$ (value As _Float, decimal_places As _Byte, length As _Byte)
    If length = 0 Then Exit Function
    Dim tempV As _Float: tempV = value
    If decimal_places Then tempV = Int(tempV * 10 ^ decimal_places + .5) / 10 ^ decimal_places
    v$ = String$(255, "0") + _Trim$(Str$(tempV))
    p = InStr(v$, ".")
    If p Then
        If decimal_places Then
            v$ = Left$(v$ + String$(255, "0"), p + decimal_places)
        Else
            v$ = Left$(v$, p - 1)
        End If
    Else
        If decimal_places Then v$ = v$ + "." + String$(decimal_places, "0")
    End If
    PaddedString$ = Right$(v$, length)
End Function


Note:  This is for positive numbers only, as I didn't need negative values when I wrote it, though you should be able to easily expand for that if necessary.  Wink

What does the above do?  It lets you specify a value for leading and trailing zeroes, to keep formatting consistent with your needs.

00.10  <-- first output
03       <-- second output, with no decimal place as we specified not to have one.
03.00   <-- third output with 2 decimal points
Reply
#5
Wow, thanks for the interesting replies! I'll dissect each one shortly.
Reply
#6
Thumbs Up 
(03-29-2023, 07:51 AM)mdijkens Wrote: Almost the same as what you posted:
Code: (Select All)
c$ = Right$("0000" + Ltrim$(Str$((n)), 4)

Yep! Once again exactly how I would do it Smile

And if used allot, generalize by making a function that does space or 0 or any other character, n times something like Steve has shown with a Pad$ function.
b = b + ...
Reply
#7
All work great, aside from a missing comma in mdijkens wonderfully simple example.

Here's a test program of mdijkens idea:

Code: (Select All)
n = 45
c$ = Right$("000" + LTrim$(Str$((n))), 3)
m = Val(c$)
Print n, c$, m
Reply
#8
yes, sorry, one bracket too much :-)
Code: (Select All)
c$ = Right$("0000" + Ltrim$(Str$(n)), 4)
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#9
this brings back memories for me, as a "former code monkey" back in my day.

we used to have to format our own strings for display as a regular programming feature, then yeah, you made it into a genericized routine.

I used to let the user save a "format string", then fed that into the pretty printing output. hey, they only have to set the format string ONCE.

format string "3.2" would yield...  000.00
format string "2.0" would yield...  00

later on, naturally a zillion functions were available for programmers to use, but, I was always a "write my own routine" kind of guy. Kept my software tight and fast, with no dependencies beyond the bare minimums.

after I got out of it? Bloat was getting bad... seemed everyone was yanking in a half a gig of "stuff" just to use ONE little function they needed. Hey... whats a few lines of code to eliminate the dependency and tighten things up.

one quick and dirty way to accomplish it? decide your maximum number of places. Lets say its 16 places for the integer portion, and 8 places for the decimals.

simply concatenate... 16 zeroes, then your integer after stripping leading space... and add on 8 trailing zeroes.
just know where your first digit locationa and last digit location are, or count up and past the decimal point. No decimal point? Integer so  Add one.
Reply




Users browsing this thread: 1 Guest(s)