Author Topic: Help formatting numbers without printing to screen  (Read 10453 times)

0 Members and 1 Guest are viewing this topic.

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #15 on: December 18, 2018, 01:00:48 pm »
I am curious what is the difference with what is wanted here and this:
https://www.qb64.org/forum/index.php?topic=840.msg100462#msg100462


almost nothing, except that I did rewrite that a little cleaner, and now it seems to work, but if you run the code I just posted in a loop, using an increment of - say - 2.4 and deleay it about 1 second or less (there is a reason for that chaos), starting var 10000000.23 (some crazy decimal.. just for use) what I see when I run it, is that around the 1million spot the comma disappears for a second then reappears.

here is a sample you can try
Code: QB64: [Select]
  1. counter = 1
  2. somenumber = 1000000000.23
  3.     LOCATE 1, 1, 0
  4.  
  5.     PRINT somenumber
  6.     somenumber = somenumber + 2.4
  7.  
  8.  
  9.     PRINT num2str$(somenumber, 3) 'use the code function i posted earlier
  10.     _DELAY (1)
  11. LOOP UNTIL counter = 1000
  12.  

the million comma seems to come and go for some reason, and I think it is how I am doing the modulous.(old fashion way vs the "%" method)
Your question is very valid. The only reason I ask is that sometimes my OCD kicks in, and I think, in this case, that I am not seeing the forest for the trees with the PRINT USING format. since it does most the work. And wondering if I am on the right track writing a custom funciton that does almost the same thing.

oooorrrrrr

is there a flag I am missing in the PRINT USING to rid the space padding ?


I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Help formatting numbers without printing to screen
« Reply #16 on: December 18, 2018, 01:14:12 pm »
That may be a glitch with the display flickering.

Try adding _DISPLAY to your loop to stop flicker.

If that doesn’t work, put a check to count commas (a DO LOOP with INSTR can do that easily enough), and then pause execution when a value appears without it.  Print that value to the screen, and we can use it to figure out why the comma would appear sometimes, but not others.

Once the fringe case is identified (if it exists), then it can be debugged/accounted for.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #17 on: December 18, 2018, 02:07:50 pm »
Code: QB64: [Select]
  1. DIM somenumber AS DOUBLE '<<<<<<<<<<< added
  2. counter = 1
  3. somenumber = 1000000000.23
  4.     CLS '<<<<<<<<<<<<< added to make sure seeing fresh number clearly
  5.     LOCATE 1, 1, 0 ' <<<< 0 to turn off cursor???
  6.  
  7.  
  8.     'somenumber = somenumber + 2.4
  9.     somenumber = somenumber + RND * 1000 - 500 '<<< to make more interesting
  10.     PRINT somenumber '<<<<<<<<<<<<<<<<< moved to compare equal values
  11.     PRINT xnum2str$(somenumber, 3) 'use the code function i posted earlier  '<<<< added the x in front
  12.     _DELAY (1)
  13. LOOP UNTIL counter = 1000
  14.  
  15.  
  16.  
  17. FUNCTION xnum2str$ (num AS DOUBLE, dec AS INTEGER)
  18.  
  19.     '// convert to number delimted string
  20.  
  21.     DIM number AS STRING
  22.     DIM precision AS STRING
  23.     DIM convert AS STRING
  24.     DIM tempStr AS STRING
  25.     DIM I AS INTEGER
  26.  
  27.     convert = STR$(num) '                                               convert it all to a strig
  28.     number = LEFT$(convert, INSTR(convert, ".") - 1) '                  store the integer
  29.     precision = MID$(convert, INSTR(convert, "."), LEN(convert)) '      store the decimal
  30.  
  31.     tempStr = ""
  32.     FOR I = LEN(number) TO 1 STEP -1 '                                  create comma delimted string
  33.         tempStr = MID$(convert, I, 1) + tempStr
  34.         IF I / 3 = INT(I / 3) THEN tempStr = "," + tempStr
  35.     NEXT
  36.     number = tempStr
  37.  
  38.  
  39.     tempStr = "" '                                                      adjust len of precisio to match
  40.     FOR I = 1 TO LEN(precision)
  41.         tempStr = tempStr + MID$(precision, I, 1)
  42.         IF I >= dec THEN EXIT FOR
  43.     NEXT
  44.     precision = tempStr
  45.     xnum2str$ = number + precision
  46.  
  47.  

This looks solid as a rock without _display using QB64 X64. I will complain precision 3, gives only 2 decimal places.

Testing with X32 and negative numbers (dec set at 2), I find error in code:


I also see that my commatose code is not handling neg numbers quite right either. dang!
« Last Edit: December 18, 2018, 02:23:30 pm by bplus »

Offline freetrav

  • Newbie
  • Posts: 45
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #18 on: December 18, 2018, 02:18:28 pm »
Just as a random side comment on this subject, I've seen other BASICs with either an SPRINT/SPRINT USING statement (SPRINT -> PRINT to a string) or a USING$ function, which is probably implemented by "riding" the code of PRINT USING. Perhaps it might be worth thinking about implementing _USING$(pattern$,value)?

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Help formatting numbers without printing to screen
« Reply #19 on: December 18, 2018, 02:44:23 pm »
Code: QB64: [Select]
  1. DIM somenumber AS DOUBLE '<<<<<<<<<<< added
  2. counter = 1
  3. somenumber = 1000000000.23
  4.     CLS '<<<<<<<<<<<<< added to make sure seeing fresh number clearly
  5.     LOCATE 1, 1, 0 ' <<<< 0 to turn off cursor???
  6.  
  7.  
  8.     'somenumber = somenumber + 2.4
  9.     somenumber = somenumber + RND * 1000 - 500 '<<< to make more interesting
  10.     PRINT somenumber '<<<<<<<<<<<<<<<<< moved to compare equal values
  11.     PRINT xnum2str$(somenumber, 3) 'use the code function i posted earlier  '<<<< added the x in front
  12.     _DELAY (1)
  13. LOOP UNTIL counter = 1000
  14.  
  15.  
  16.  
  17. FUNCTION xnum2str$ (num AS DOUBLE, dec AS INTEGER)
  18.  
  19.     '// convert to number delimted string
  20.  
  21.     DIM number AS STRING
  22.     DIM precision AS STRING
  23.     DIM convert AS STRING
  24.     DIM tempStr AS STRING
  25.     DIM I AS INTEGER
  26.  
  27.     convert = STR$(num) '                                               convert it all to a strig
  28.     number = LEFT$(convert, INSTR(convert, ".") - 1) '                  store the integer
  29.     precision = MID$(convert, INSTR(convert, "."), LEN(convert)) '      store the decimal
  30.  
  31.     tempStr = ""
  32.     FOR I = LEN(number) TO 1 STEP -1 '                                  create comma delimted string
  33.         tempStr = MID$(convert, I, 1) + tempStr
  34.         IF I / 3 = INT(I / 3) THEN tempStr = "," + tempStr
  35.     NEXT
  36.     number = tempStr
  37.  
  38.  
  39.     tempStr = "" '                                                      adjust len of precisio to match
  40.     FOR I = 1 TO LEN(precision)
  41.         tempStr = tempStr + MID$(precision, I, 1)
  42.         IF I >= dec THEN EXIT FOR
  43.     NEXT
  44.     precision = tempStr
  45.     xnum2str$ = number + precision
  46.  
  47.  

This looks solid as a rock without _display using QB64 X64. I will complain precision 3, gives only 2 decimal places.

Testing with X32 and negative numbers (dec set at 2), I find error in code:


I also see that my commatose code is not handling neg numbers quite right either. dang!

Just check for negative values.  If found, use ABS() on the number, generate the result, and then add a “-“ to the end result.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #20 on: December 18, 2018, 02:52:45 pm »
Yeah I have it fixed in commatose:
Code: QB64: [Select]
  1. DIM somenumber AS DOUBLE '<<<<<<<<<<< added
  2. counter = 1
  3. somenumber = 0
  4.     CLS '<<<<<<<<<<<<< added to make sure seeing fresh number clearly
  5.     LOCATE 1, 1, 0 ' <<<< 0 to turn off cursor???
  6.  
  7.     'somenumber = somenumber + 2.4
  8.     somenumber = somenumber - RND * 10 + 4 '<<< to make more interesting  drift down
  9.     PRINT "               PRINT somenumber: "; somenumber '<<<<<<<<<<<<<<<<< moved to compare equal values
  10.     PRINT " PRINT xnum2str$(somenumber, 3): "; xnum2str$(somenumber, 3) 'use the code function i posted earlier  '<<<< added the x in front
  11.     PRINT "PRINT Commatose$(somenumber, 3): "; Commatose$(somenumber, 3)
  12.     _LIMIT 60
  13. LOOP UNTIL counter = 1000
  14.  
  15.  
  16.  
  17. FUNCTION xnum2str$ (num AS DOUBLE, dec AS INTEGER)
  18.  
  19.     '// convert to number delimted string
  20.  
  21.     DIM number AS STRING
  22.     DIM precision AS STRING
  23.     DIM convert AS STRING
  24.     DIM tempStr AS STRING
  25.     DIM I AS INTEGER
  26.  
  27.     convert = STR$(num) '                                               convert it all to a strig
  28.     number = LEFT$(convert, INSTR(convert, ".") - 1) '                  store the integer
  29.     precision = MID$(convert, INSTR(convert, "."), LEN(convert)) '      store the decimal
  30.  
  31.     tempStr = ""
  32.     FOR I = LEN(number) TO 1 STEP -1 '                                  create comma delimted string
  33.         tempStr = MID$(convert, I, 1) + tempStr
  34.         IF I / 3 = INT(I / 3) THEN tempStr = "," + tempStr
  35.     NEXT
  36.     number = tempStr
  37.  
  38.  
  39.     tempStr = "" '                                                      adjust len of precisio to match
  40.     FOR I = 1 TO LEN(precision)
  41.         tempStr = tempStr + MID$(precision, I, 1)
  42.         IF I >= dec THEN EXIT FOR
  43.     NEXT
  44.     precision = tempStr
  45.     xnum2str$ = number + precision
  46.  
  47.  
  48. FUNCTION Commatose$ (value AS DOUBLE, precision AS INTEGER)
  49.     DIM v AS DOUBLE
  50.     v = value 'copy so it doesn't get changed
  51.     IF v < 0 THEN s$ = "-": v = v * -1 ELSE s$ = ""
  52.  
  53.     sv$ = LTRIM$(STR$(v)) '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ltrim$ remove leading space!
  54.     dot = INSTR(sv$, ".")
  55.     IF dot THEN
  56.         i$ = MID$(sv$, 1, dot - 1)
  57.         d$ = LEFT$(MID$(sv$, dot + 1) + STRING$(precision, "0"), precision)
  58.     ELSE
  59.         i$ = sv$
  60.         d$ = STRING$(precision, "0")
  61.     END IF
  62.     FOR i = LEN(i$) TO 1 STEP -1
  63.         c = c + 1
  64.         IF c = 4 THEN c = 1: b$ = "," + b$
  65.         b$ = MID$(i$, i, 1) + b$
  66.     NEXT
  67.     Commatose$ = s$ + b$ + "." + d$
  68.  
  69.  

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #21 on: December 18, 2018, 04:58:37 pm »
That may be a glitch with the display flickering.

Try adding _DISPLAY to your loop to stop flicker.

If that doesn’t work, put a check to count commas (a DO LOOP with INSTR can do that easily enough), and then pause execution when a value appears without it.  Print that value to the screen, and we can use it to figure out why the comma would appear sometimes, but not others.

Once the fringe case is identified (if it exists), then it can be debugged/accounted for.  ;)

you might be on to something...
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #22 on: December 18, 2018, 05:03:24 pm »
btw, after reading this and my otherone - they are extremely similar, it is the same issue, with a sleight variation - any chance a mod can move this to that thread. Makes more sense.

I think I just solved it too, it is something to do with the way I am parsing the string

using anything larger than 100k or 1mil the comma drifts. while I will look here in a sec, but for public curiosity, is qb64 strings zero based or 1?

abcdef
does "a" position = zero or 1?

I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Help formatting numbers without printing to screen
« Reply #23 on: December 18, 2018, 05:06:49 pm »
btw, after reading this and my otherone - they are extremely similar, it is the same issue, with a sleight variation - any chance a mod can move this to that thread. Makes more sense.

I think I just solved it too, it is something to do with the way I am parsing the string

using anything larger than 100k or 1mil the comma drifts. while I will look here in a sec, but for public curiosity, is qb64 strings zero based or 1?

abcdef
does "a" position = zero or 1?

1st  position
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #24 on: December 18, 2018, 08:38:39 pm »
OK. works!! Got it. Woot


Code: QB64: [Select]
  1. FUNCTION num2str$ (num AS DOUBLE, dec AS INTEGER)
  2.  
  3.     '// convert to number delimted string
  4.  
  5.     DIM number AS STRING '                                              stores whole number(w/o dec) minus "."
  6.     DIM precision AS STRING '                                           stores decimals (minus ".")
  7.     DIM convert AS STRING '                                             stores the orginal number in string format
  8.     DIM tempStr AS STRING '                                             used to create the new formated string
  9.     DIM I, j AS INTEGER '                                               i=loop counter, j= delimeter counter
  10.  
  11.     convert = STR$(num) '                                               convert it all to a strig
  12.     number = LEFT$(convert, INSTR(convert, ".") - 1) '                  store the integer
  13.     precision = MID$(convert, INSTR(convert, ".") + 1, LEN(convert)) '  store the decimal
  14.     number = RTRIM$(LTRIM$(number)) '                                   trim it up
  15.    
  16.        IF num < 1000 THEN '                                                if its less than 1000, then no comma needed
  17.         num2str$ = number + "." + LEFT$(precision, dec) '               assign function for dec (precision)
  18.         EXIT SUB '                                                      leave this sub now
  19.     END IF
  20.  
  21.  
  22.  
  23.  
  24.     j = 1 '                                                             set delimeter counter
  25.     tempStr = ""
  26.     FOR I = LEN(number) TO 1 STEP -1 '                                  count from the right to left of number
  27.  
  28.         IF j > 3 THEN '                                                 if delimeter counter is > 3 then
  29.             tempStr = "," + tempStr '                                   add a comma
  30.             j = 1 '                                                     reset the delimeter counter
  31.         END IF
  32.  
  33.  
  34.         tempStr = MID$(number, I, 1) + tempStr '                        add the next digit from "number" to tempstr
  35.         j = j + 1 '                                                     increase the delimeter counter
  36.  
  37.     NEXT '                                                              keep looping
  38.     number = tempStr '                                                  reassign number to the actual string created
  39.  
  40.  
  41.     tempStr = "" '                                                      clear tempStr so we can make the percision
  42.     FOR I = 1 TO LEN(precision) '                                       start looping through dec
  43.         tempStr = tempStr + MID$(precision, I, 1) '                     create it
  44.         IF I >= dec THEN EXIT FOR '                                     is it the number of places(dec) we want? exit this loop
  45.     NEXT
  46.     precision = tempStr '                                               assign the precision var to the newly created decimal length
  47.     num2str$ = number + "." + precision '                               return it back as a fll string with "."
  48.  
  49.  
  50.  

the only way I could get this to work was to use the "J" loop.
I tried the MOD, and I tried an old method of

Code: QB64: [Select]
  1. if i/3 = int(i/3) then add a comma

none of them worked.
This does.
Returns a comma delimited string variable from an integer or double

Opinions? Suggestions?

I had to stop looking at my Steam Que so I could focus on this LOL...
« Last Edit: December 18, 2018, 10:45:58 pm by xra7en »
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline Fifi

  • Forum Regular
  • Posts: 181
    • View Profile
    • My small QB64 contribution
Re: Help formatting numbers without printing to screen
« Reply #25 on: December 19, 2018, 05:11:13 am »
Just as a random side comment on this subject, I've seen other BASICs with either an SPRINT/SPRINT USING statement (SPRINT -> PRINT to a string) or a USING$ function, which is probably implemented by "riding" the code of PRINT USING. Perhaps it might be worth thinking about implementing _USING$(pattern$,value)?

As another side comment: would it be so difficult to interface (implement) two new reserved words with the C/C++ printf() and sprintf() stdio.h functions using their syntax and parameters that would avoid to "translate" the current PRINT USING while being more powerfull?

Just my two cents.
It's better to look like an idiot for a short time while asking something obvious to an expert than pretending to be smart all your life. (C) Me.

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #26 on: December 19, 2018, 07:09:08 am »
Just as a random side comment on this subject, I've seen other BASICs with either an SPRINT/SPRINT USING statement (SPRINT -> PRINT to a string) or a USING$ function, which is probably implemented by "riding" the code of PRINT USING. Perhaps it might be worth thinking about implementing _USING$(pattern$,value)?

As another side comment: would it be so difficult to interface (implement) two new reserved words with the C/C++ printf() and sprintf() stdio.h functions using their syntax and parameters that would avoid to "translate" the current PRINT USING while being more powerfull?

Just my two cents.

hey, every penny counts :-)
I used to work with C++/# in my old BBS days. Wish I would have stuck with it, because I went from Telegard->Invision-Infinity (all pascal) to Proboard(C++), very weird change. Not only that, with all the pascal making a hit, I thought that would be the language of choice, and BOOM here comes "C" LOL

OK I digress.....

sprint, print etc.. all output to the screen/console

I needed something that returned a var that does the same thing.
or at minimum a PHP version of "number_format" which does not require a template. Actually, I should check that script source out and see how they did that (slow thinker LOL)

I do like your idea, however Im wanting to keep the langs separate (at least for now).

Nice Idea though

EDIT:
================================

Here is afunctional version in PHP... The original is in C, So will look at that. I personally think this might be a useful function to add in QB64 IMHO
Code: QB64: [Select]
  1. function number_format($num){
  2.   $num=(string)$num;
  3.   $len=strlen($num);
  4.   $newnum='';
  5.   for ($i=0; $i<$len; ++$i) {
  6.     if (($i%3==0) && $i) {
  7.       $newnum=','.$newnum;
  8.     }
  9.     $newnum=$num[$len-$i-1].$newnum;
  10.   }
  11.   return $newnum;
  12. }
« Last Edit: December 19, 2018, 07:11:33 am by xra7en »
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #27 on: December 19, 2018, 07:42:47 am »
Hi
fine to add meself to this thread again

I have wrote a my routine... :-)
yes! Why? As someone knows the way to write numbers in italian is different from that used here, (also date and some few other things...) so I try to make my algorithm in QB64 working on string format and letting to show international format (, for thousand and . for decimal or that italian that is the inverse system  i.e.  international 1,000,009.999 = italian 1.000.009,999 ). So here my work.

I take your code and add my function.
PS: Just modify the number maker to have greater numbers... and both negative and positive numbers...on program's controls you can exit by keyboard and stop and go by space/anyOtherKey.

Attached are the  images of results...


as you can see in image3
1.  I am not able to manage Commatose$'s output, I have got a flickering passing from negative to positive numbers...
2. xnum2str$ have a bug...

Thanks to read and to reply

PS I have no knowledge in the matter please tell me, but after the decimal point do the digits need no formatting with separator ?


PSS sorry I have forgotten to post the code....
Code: QB64: [Select]
  1. DIM somenumber AS DOUBLE '<<<<<<<<<<< added
  2. DIM counter AS INTEGER, signs AS INTEGER
  3.  
  4. counter = 1
  5. somenumber = 0
  6.     CLS '<<<<<<<<<<<<< added to make sure seeing fresh number clearly
  7.     LOCATE 1, 1, 0 ' <<<< 0 to turn off cursor???
  8.     IF (RND * 5 + 1) > 3 THEN signs = -1 ELSE signs = 1
  9.  
  10.     somenumber = (somenumber - (RND * 10) + 40000000) * signs
  11.     PRINT "                    PRINT somenumber: "; somenumber
  12.     PRINT " PRINT xnum2str$(somenumber, 3):      "; xnum2str$(somenumber, 3)
  13.     PRINT " PRINT num2str$(somenumber, 3):       "; num2str$(somenumber, 3)
  14.     PRINT "PRINT Commatose$(somenumber, 3):       "; Commatose$(somenumber, 3)
  15.     PRINT "PRINT MyNumToString$(somenumber, 3, 1)"; MyNumToString$(somenumber, 3, 1)
  16.     PRINT "PRINT MyNumToString$(somenumber, 3, 2)"; MyNumToString$(somenumber, 3, 2)
  17.     _LIMIT 60
  18.     IF _KEYDOWN(32) THEN SLEEP
  19.  
  20.  
  21.  
  22. FUNCTION MyNumToString$ (num AS DOUBLE, dec AS INTEGER, mode AS INTEGER)
  23.     DIM Thousand AS STRING * 1, Decimal AS STRING * 1, NumberStringed AS STRING
  24.     DIM DecimalString AS STRING, NumberString AS STRING, Minus AS STRING * 1
  25.     DIM DecimalPoint AS INTEGER, LenghtDecimal AS INTEGER, LenghtInteger AS INTEGER
  26.     DIM Starter AS INTEGER, Counter AS INTEGER, Steps AS INTEGER
  27.     IF mode = 1 THEN
  28.         ' english puntaction for number
  29.         Thousand = ","
  30.         Decimal = "."
  31.     ELSEIF mode = 2 THEN
  32.         ' italian puntaction for number
  33.         Thousand = "."
  34.         Decimal = ","
  35.     ELSE
  36.         PRINT "invalid Mode setting"
  37.         EXIT FUNCTION
  38.     END IF
  39.     Minus = ""
  40.     NumberStringed = LTRIM$(STR$(num))
  41.     IF (num < 0) AND INSTR(NumberStringed, "-") = 1 THEN
  42.         NumberStringed = MID$(NumberStringed, 2)
  43.         Minus = "-"
  44.     END IF
  45.     DecimalPoint = INSTR(NumberStringed, ".")
  46.     DecimalString = RIGHT$(NumberStringed, LEN(NumberStringed) - DecimalPoint)
  47.     LenghtDecimal = LEN(RIGHT$(NumberStringed, LEN(NumberStringed) - DecimalPoint))
  48.     NumberString = LEFT$(NumberStringed, DecimalPoint - 1)
  49.     LenghtInteger = LEN(NumberString)
  50.  
  51.     IF (LenghtInteger < 4) THEN
  52.         MyNumToString$ = Minus + NumberString + Decimal + LEFT$(DecimalString, dec)
  53.     ELSE
  54.         NumberStringed = ""
  55.         Starter = (LenghtInteger MOD 3)
  56.         Steps = INT(LenghtInteger / 3)
  57.         IF Starter > 0 THEN NumberStringed = LEFT$(NumberString, Starter) + Thousand
  58.         FOR Counter = 0 TO Steps - 1
  59.             NumberStringed = NumberStringed + MID$(NumberString, Starter + (Counter * 3) + 1, 3) + Thousand
  60.         NEXT
  61.         NumberStringed = LEFT$(NumberStringed, LEN(NumberStringed) - 1)
  62.         MyNumToString$ = Minus + NumberStringed + Decimal + LEFT$(DecimalString, dec)
  63.     END IF
  64.  
  65.  
  66. FUNCTION num2str$ (num AS DOUBLE, dec AS INTEGER)
  67.  
  68.     '// convert to number delimted string
  69.  
  70.     DIM number AS STRING '                                              stores whole number(w/o dec) minus "."
  71.     DIM precision AS STRING '                                           stores decimals (minus ".")
  72.     DIM convert AS STRING '                                             stores the orginal number in string format
  73.     DIM tempStr AS STRING '                                             used to create the new formated string
  74.     DIM I, j AS INTEGER '                                               i=loop counter, j= delimeter counter
  75.  
  76.     convert = STR$(num) '                                               convert it all to a strig
  77.     number = LEFT$(convert, INSTR(convert, ".") - 1) '                  store the integer
  78.     precision = MID$(convert, INSTR(convert, ".") + 1, LEN(convert)) '  store the decimal
  79.     number = RTRIM$(LTRIM$(number)) '                                   trim it up
  80.  
  81.     IF num < 1000 THEN '                                                if its less than 1000, then no comma needed
  82.         num2str$ = number + "." + LEFT$(precision, dec) '               assign function for dec (precision)
  83.         EXIT SUB '                                                      leave this sub now
  84.     END IF
  85.  
  86.  
  87.  
  88.  
  89.     j = 1 '                                                             set delimeter counter
  90.     tempStr = ""
  91.     FOR I = LEN(number) TO 1 STEP -1 '                                  count from the right to left of number
  92.  
  93.         IF j > 3 THEN '                                                 if delimeter counter is > 3 then
  94.             tempStr = "," + tempStr '                                   add a comma
  95.             j = 1 '                                                     reset the delimeter counter
  96.         END IF
  97.  
  98.  
  99.         tempStr = MID$(number, I, 1) + tempStr '                        add the next digit from "number" to tempstr
  100.         j = j + 1 '                                                     increase the delimeter counter
  101.  
  102.     NEXT '                                                              keep looping
  103.     number = tempStr '                                                  reassign number to the actual string created
  104.  
  105.  
  106.     tempStr = "" '                                                      clear tempStr so we can make the percision
  107.     FOR I = 1 TO LEN(precision) '                                       start looping through dec
  108.         tempStr = tempStr + MID$(precision, I, 1) '                     create it
  109.         IF I >= dec THEN EXIT FOR '                                     is it the number of places(dec) we want? exit this loop
  110.     NEXT
  111.     precision = tempStr '                                               assign the precision var to the newly created decimal length
  112.     num2str$ = number + "." + precision '                               return it back as a fll string with "."
  113.  
  114.  
  115. FUNCTION xnum2str$ (num AS DOUBLE, dec AS INTEGER)
  116.  
  117.     '// convert to number delimted string
  118.  
  119.     DIM number AS STRING
  120.     DIM precision AS STRING
  121.     DIM convert AS STRING
  122.     DIM tempStr AS STRING
  123.     DIM I AS INTEGER
  124.  
  125.     convert = STR$(num) '                                               convert it all to a strig
  126.     number = LEFT$(convert, INSTR(convert, ".") - 1) '                  store the integer
  127.     precision = MID$(convert, INSTR(convert, "."), LEN(convert)) '      store the decimal
  128.  
  129.     tempStr = ""
  130.     FOR I = LEN(number) TO 1 STEP -1 '                                  create comma delimted string
  131.         tempStr = MID$(convert, I, 1) + tempStr
  132.         IF I / 3 = INT(I / 3) THEN tempStr = "," + tempStr
  133.     NEXT
  134.     number = tempStr
  135.  
  136.  
  137.     tempStr = "" '                                                      adjust len of precisio to match
  138.     FOR I = 1 TO LEN(precision)
  139.         tempStr = tempStr + MID$(precision, I, 1)
  140.         IF I >= dec THEN EXIT FOR
  141.     NEXT
  142.     precision = tempStr
  143.     xnum2str$ = number + precision
  144.  
  145.  
  146. FUNCTION Commatose$ (value AS DOUBLE, precision AS INTEGER)
  147.     DIM v AS DOUBLE
  148.     v = value 'copy so it doesn't get changed
  149.     IF v < 0 THEN s$ = "-": v = v * -1 ELSE s$ = ""
  150.  
  151.     sv$ = LTRIM$(STR$(v)) '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ltrim$ remove leading space!
  152.     dot = INSTR(sv$, ".")
  153.     IF dot THEN
  154.         i$ = MID$(sv$, 1, dot - 1)
  155.         d$ = LEFT$(MID$(sv$, dot + 1) + STRING$(precision, "0"), precision)
  156.     ELSE
  157.         i$ = sv$
  158.         d$ = STRING$(precision, "0")
  159.     END IF
  160.     FOR i = LEN(i$) TO 1 STEP -1
  161.         c = c + 1
  162.         IF c = 4 THEN c = 1: b$ = "," + b$
  163.         b$ = MID$(i$, i, 1) + b$
  164.     NEXT
  165.     Commatose$ = s$ + b$ + "." + d$
  166.  
« Last Edit: December 19, 2018, 11:55:34 am by TempodiBasic »
Programming isn't difficult, only it's  consuming time and coffee

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #28 on: December 19, 2018, 08:14:55 am »
Looks very nice - AND you seem to have a dilemma that I have. those darn leading spaces for digits that do not fill it.
Thus why I tried my hand at making a custom function,

According to the definition - if I read it right:

Quote
  #    Denotes a numerical digit. An appropriate number of digits should be used for values received.

so you kinda have to guess the amount of digits  on a dynamic application. 

HOWEVER FreeTrav gave me an Idea (sorta my original question about using the "PRINT USING" to do the brunt of the work, and I came up with this:
It seems to solve the goofy leading spaces for digits that are not there. It adds a hash for each digit dynamically THEN IT USES THE PRINT USING
Code: QB64: [Select]
  1. SUB number_format (num AS DOUBLE, flt AS INTEGER)
  2.     DIM number AS STRING '                                              stores whole number(w/o dec) minus "."
  3.     DIM convert AS STRING '                                             stores the orginal number in string format
  4.     DIM I AS INTEGER '                                                  i=loop counter delimeter counter
  5.     DIM tpl AS STRING '                                                 .. using template
  6.  
  7.     convert = STR$(num) '                                               convert it all to a strig
  8.     IF RIGHT$(convert, 1) <> "." THEN convert = convert + "." '         weird fix for lower numbers
  9.     number = LEFT$(convert, INSTR(convert, ".") - 1) '                  store the integer
  10.     number = RTRIM$(LTRIM$(number)) '                                   trim it up
  11.  
  12.     tpl = "" '                                                          create a template string for USING
  13.  
  14.     FOR I = 1 TO LEN(number): tpl = tpl + "#": NEXT '                   add a hash per digit per integer digit
  15.     tpl = tpl + "," '                                                   set the comma tag
  16.     IF flt > 0 THEN '                                                   is the decimal count set?
  17.         tpl = tpl + "." '                                               add the decimal tag
  18.         FOR I = 1 TO flt: tpl = tpl + "#": NEXT '                       how many places (as per dec)
  19.     END IF
  20.     '    PRINT "tpl for "; num
  21.     '    PRINT tpl
  22.     PRINT USING tpl; num '                                              now PRINT USING should look cleaner
  23.  

So now instead of "re-inventing the wheel" I just changed it a little. Now there are no spaces, the decimal and digits can grow dynamically

whatcha think? ya?
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: Help formatting numbers without printing to screen
« Reply #29 on: December 19, 2018, 08:17:50 am »
Hi
fine to add meself to this thread again

I have wrote a my routine... :-)
yes! Why? As someone knows the way to write numbers in italian is different from that used here, (also date and some few other things...) so I try to make my algorithm in QB64 working on string format and letting to show international format (, for thousand and . for decimal or that italian that is the inverse system  i.e.  international 1,000,009.999 = italian 1.000.009,999 ). So here my work.


That is very interesting, If I understand...
Italian uses a ","(comma) for a decimal notation and a "."(dot) for thousands separator?
If so we could change the function to ask for a delimiter.
 
thanks for that info.
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!