Author Topic: Question about number formatting  (Read 4196 times)

0 Members and 1 Guest are viewing this topic.

Offline DimColby

  • Newbie
  • Posts: 1
    • View Profile
Question about number formatting
« on: February 15, 2021, 06:02:36 pm »
Hi all. I have a program that displays numbers converted to a string. However sometimes, apparently randomly, it switches to exponential notation when a number is close enough to zero and it only correctly processes decimal notation. Is there any way to force it to only use decimal notation?  Thanks in advance.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Question about number formatting
« Reply #1 on: February 15, 2021, 06:16:05 pm »
Yes,

Just a moment...

Here is my demo of Steve's sub, N2S$ (Number To String)
Code: QB64: [Select]
  1. _TITLE "N2S$ testing for a scientific notation remover" 'b+ 2020-09-04
  2. ' source of bug tracked down 2020-09-08
  3. ' looks pretty good except for one little bug fixed now
  4.  
  5. 'It was because i was not dim'd as an integer!!!
  6. DIM i AS INTEGER '<<<<<<<<<<<<<<<<<<<< Oh man!!!!  this was the problem!!! Discovered 2020-09-08
  7.  
  8. IF 0 THEN ' < 0 to skip section, 1 to run section
  9.     DIM n AS INTEGER '<<<<<<<<<<< comment out to test single
  10.     n = 1 ' has an odd bug jump -7 to -8 moves right 1 extra 0   fixed!!
  11.     FOR i = 0 TO 20
  12.         PRINT i,
  13.         LOCATE CSRLIN, 5: PRINT N2S$(STR$(n * 10 ^ -i));
  14.         LOCATE CSRLIN, 54: PRINT N2S$(STR$(n * 10 ^ i))
  15.     NEXT
  16.     BEEP
  17.     n## = 1 ' but this OK too
  18.     'n## = 27.0123456789 'OK
  19.     'n## = (1 / 3) 'OK
  20.     FOR i = 0 TO 20
  21.         PRINT i;
  22.         LOCATE CSRLIN, 5: PRINT N2S$(STR$(n## * 10 ^ -i));
  23.         LOCATE CSRLIN, 54: PRINT N2S$(STR$(n## * 10 ^ i))
  24.     NEXT
  25.     BEEP
  26.  
  27. FUNCTION N2S$ (EXP$) 'remove scientific Notation to String (~40 LOC)
  28.     'SMcNeill Jan 7, 2020 ref: https://www.qb64.org/forum/index.php?topic=1555.msg112989#msg112989
  29.     'Last Function in code marked Best Answer (removed debug comments and blank lines added these 2 lines.)
  30.     t$ = LTRIM$(RTRIM$(EXP$))
  31.     IF LEFT$(t$, 1) = "-" OR LEFT$(t$, 1) = "N" THEN sign$ = "-": t$ = MID$(t$, 2)
  32.     dp = INSTR(t$, "D+"): dm = INSTR(t$, "D-")
  33.     ep = INSTR(t$, "E+"): em = INSTR(t$, "E-")
  34.     check1 = SGN(dp) + SGN(dm) + SGN(ep) + SGN(em)
  35.     IF check1 < 1 OR check1 > 1 THEN N2S = _TRIM$(EXP$): EXIT SUB 'If no scientic notation is found, or if we find more than 1 type, it's not SN!
  36.     SELECT CASE l 'l now tells us where the SN starts at.
  37.         CASE IS < dp: l = dp
  38.         CASE IS < dm: l = dm
  39.         CASE IS < ep: l = ep
  40.         CASE IS < em: l = em
  41.     END SELECT
  42.     l$ = LEFT$(t$, l - 1) 'The left of the SN
  43.     r$ = MID$(t$, l + 1): r&& = VAL(r$) 'The right of the SN, turned into a workable long
  44.     IF INSTR(l$, ".") THEN 'Location of the decimal, if any
  45.         IF r&& > 0 THEN
  46.             r&& = r&& - LEN(l$) + 2
  47.         ELSE
  48.             r&& = r&& + 1
  49.         END IF
  50.         l$ = LEFT$(l$, 1) + MID$(l$, 3)
  51.     END IF
  52.     SELECT CASE r&&
  53.         CASE 0 'what the heck? We solved it already?
  54.             'l$ = l$
  55.         CASE IS < 0
  56.             FOR i = 1 TO -r&&
  57.                 l$ = "0" + l$
  58.             NEXT
  59.             l$ = "." + l$
  60.         CASE ELSE
  61.             FOR i = 1 TO r&&
  62.                 l$ = l$ + "0"
  63.             NEXT
  64.             l$ = l$
  65.     END SELECT
  66.     N2S$ = sign$ + l$
  67.  
  68.  

For discussion see here:
https://www.qb64.org/forum/index.php?topic=2985.msg122404#msg122404

Welcome to the forum @DimColby
Try it, like it or ask for more help ;-))
« Last Edit: February 15, 2021, 06:22:15 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Question about number formatting
« Reply #2 on: February 15, 2021, 06:21:46 pm »
PRINT USING "###.#######"; number#
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: Question about number formatting
« Reply #3 on: February 15, 2021, 06:43:47 pm »
Well Steve that's just plain too easy! ;-))

Maybe you can explain when to use which?

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Question about number formatting
« Reply #4 on: February 15, 2021, 06:50:03 pm »
Well Steve that's just plain too easy! ;-))

Maybe you can explain when to use which?

One is to simply display your value in decimal form; the other is to completely convert out of scientific notation to string, for processing or using in string math routines.  ;)

Since he's just looking to display the text in a certain format, I'd just go the easy route and stick with PRINT USING.  :)
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: Question about number formatting
« Reply #5 on: February 15, 2021, 07:10:43 pm »
LOL lovely, but what if he wants to show 0's ?

https://www.qb64.org/wiki/PRINT_USING 
« Last Edit: February 15, 2021, 07:32:49 pm by bplus »

Offline zaadstra

  • Newbie
  • Posts: 78
    • View Profile
Re: Question about number formatting
« Reply #6 on: February 16, 2021, 05:43:23 pm »
Or just using INT:

Code: QB64: [Select]
  1. INT(yourvalue*100)/100

Gives two digits after decimal dot, doesn't show them if they are zero,  e.g. 765.4

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Question about number formatting
« Reply #7 on: February 19, 2021, 05:52:04 pm »
Or just using INT:

Code: QB64: [Select]
  1. INT(yourvalue*100)/100

Gives two digits after decimal dot, doesn't show them if they are zero,  e.g. 765.4

I found a point where that doesn't work for some reason. At least my system won't process it at a certain point.

Run this snippet of code. It's a km to AU conversion from a bigger project of mine. It always throws exponential notation at the .07 point, but not before and not after. Does it in the dev build AND in 1.4

Code: QB64: [Select]
  1. Screen _NewImage(600, 600, 32)
  2. Const KMtoAU = 149597900
  3. d## = 5000000
  4.     d## = d## + 50000
  5.     If d## < 9500000 Then
  6.         d$ = Str$(Int(d##)) + "km"
  7.     Else
  8.         d$ = Str$(_Round((d## / KMtoAU) * 100) / 100) + "AU" 'yields 7.000...001D-02 between .06 & .08 both _round & INT do it
  9.     End If
  10.     Cls
  11.     _PrintString (160, 0), Str$(d##)
  12.     _PrintString (160, 48), "Dist:" + d$
  13.     _Limit 10
  14.     _Display
  15. Loop Until d## > 20000000
  16.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Question about number formatting
« Reply #8 on: February 19, 2021, 06:19:03 pm »
You mean something simple, like string math?

Code: QB64: [Select]
  1. INPUT "Limit Display: "; limit&&
  2. LINE INPUT "Use Rounding? Y/N: "; ans$
  3. IF UCASE$(ans$) = "Y" THEN
  4.     round_total% = -1
  5.     LINE INPUT "Show if Rounded? Y/N: "; ans$
  6.     IF UCASE$(ans$) = "Y" THEN show_rounding% = -1 ELSE show_rounding% = 0
  7.     round_total% = 0
  8. LINE INPUT "Display in Scientific Notation? Y/N: "; ans$
  9. IF UCASE$(ans$) = "Y" THEN
  10.     snconvert% = -1
  11.     snconvert% = 0
  12.     LINE INPUT "Display in Dollars and Cents? Y/N: "; ans$
  13.     IF UCASE$(ans$) = "Y" THEN currency_display% = -1 ELSE currency_display% = 0
  14.     LINE INPUT "Display Results with Commas? Y/N: "; ans$
  15. IF UCASE$(ans$) = "Y" THEN comma_display% = -1 ELSE comma_display% = 0
  16.     DO
  17.         LINE INPUT "Number: "; stringmathb$
  18.         IF UCASE$(stringmathb$) = "C" THEN RUN
  19.         origb$ = stringmathb$
  20.         CALL stringmath(stringmatha$, operator$, stringmathb$, runningtotal$, snconvert%, round_total%, show_rounding%, comma_display%, currency_display%, limit&&)
  21.         IF stringmathb$ <> "invalid number" AND stringmathb$ <> "overflow" THEN
  22.             EXIT DO
  23.         ELSE
  24.             PRINT stringmathb$
  25.         END IF
  26.     LOOP
  27.     IF operator$ <> "" THEN
  28.         DO UNTIL INSTR(origa$, ",") = 0
  29.             origa$ = MID$(origa$, 1, INSTR(origa$, ",") - 1) + MID$(origa$, INSTR(origa$, ",") + 1)
  30.         LOOP
  31.         DO UNTIL INSTR(origb$, ",") = 0
  32.             origb$ = MID$(origb$, 1, INSTR(origb$, ",") - 1) + MID$(origb$, INSTR(origb$, ",") + 1)
  33.         LOOP
  34.         IF INSTR(origb$, "$") THEN origb$ = MID$(origb$, 1, INSTR(origb$, "$") - 1) + MID$(origb$, INSTR(origb$, "$") + 1)
  35.         SELECT CASE orig_operator$
  36.             CASE "+"
  37.                 runningtotal# = VAL(origa$) + VAL(origb$)
  38.             CASE "-"
  39.                 runningtotal# = VAL(origa$) - VAL(origb$)
  40.             CASE "*"
  41.                 runningtotal# = VAL(origa$) * VAL(origb$)
  42.             CASE "/"
  43.                 runningtotal# = VAL(origa$) / VAL(origb$)
  44.             CASE "C", "c"
  45.                 RUN
  46.         END SELECT
  47.         origa$ = LTRIM$(STR$(runningtotal#))
  48.         COLOR 8, 0: PRINT "Numeric Total: "; origa$: COLOR 7, 0
  49.         PRINT "String Total:  "; runningtotal$
  50.     ELSE
  51.         origa$ = runningtotal$: IF INSTR(origa$, "$") THEN origa$ = MID$(origa$, 1, INSTR(origa$, "$") - 1) + MID$(origa$, INSTR(origa$, "$") + 1)
  52.     END IF
  53.     COLOR 2, 0: PRINT "Operator: +-/*: ";: COLOR 7, 0
  54.     DO
  55.         operator$ = INKEY$
  56.         IF LEN(operator$) THEN
  57.             IF operator$ = CHR$(27) THEN SYSTEM
  58.             IF INSTR("-+/*=8cC", operator$) THEN EXIT DO
  59.         END IF
  60.     LOOP
  61.     IF UCASE$(operator$) = "C" THEN RUN
  62.     IF operator$ = "=" THEN operator$ = "+"
  63.     IF operator$ = "8" THEN operator$ = "*"
  64.     orig_operator$ = operator$
  65.     PRINT operator$
  66.  
  67. SUB stringmath (stringmatha$, operator$, stringmathb$, runningtotal$, snconvert%, round_total%, show_rounding%, comma_display%, currency_display%, limit&&)
  68. stringmathround$ = ""
  69. IF limit&& > 2147483640 THEN limit&& = 2147483640
  70. IF limit&& = 0 THEN limit&& = 70 ' Default.
  71.  
  72. IF RIGHT$(UCASE$(runningtotal$), 1) = "R" THEN runningtotal$ = MID$(runningtotal$, 1, LEN(runningtotal$) - 1) 'Strip off rounding designation.
  73. ' Check running total. If S.N. convert to numeric for operations.
  74. IF INSTR(runningtotal$, ",") <> 0 OR INSTR(runningtotal$, "e") <> 0 THEN
  75.     holdstringmathb$ = stringmathb$
  76.     stringmathb$ = runningtotal$
  77.     IF INSTR(runningtotal$, ",") <> 0 THEN GOSUB comma_removal ELSE GOSUB scientific_to_numeric
  78.     runningtotal$ = stringmathb$: stringmathb$ = holdstringmathb$: holdstringmathb$ = ""
  79. ' Check input number. If S.N. convert to numeric for operations.
  80. IF INSTR(UCASE$(stringmathb$), "D") <> 0 OR INSTR(UCASE$(stringmathb$), "E") <> 0 THEN
  81.     GOSUB validate_string_number
  82.     IF stringmathb$ = "invalid number" THEN EXIT SUB
  83.     GOSUB scientific_to_numeric
  84.  
  85. IF runningtotal$ = "" THEN
  86.     GOSUB validate_string_number
  87.     IF stringmathb$ = "invalid number" THEN EXIT SUB
  88.  
  89.     IF LEFT$(stringmathb$, 1) = "-" THEN
  90.         stringmathb$ = MID$(stringmathb$, 2)
  91.         n2sign$ = "-"
  92.     ELSE
  93.         n2sign$ = ""
  94.     END IF
  95.     GOSUB limit_round_convert
  96.     IF stringmathb$ = "overflow" THEN
  97.         n2sign$ = "": PRINT "Validated: "; stringmathb$: EXIT SUB
  98.     END IF
  99.     runningtotal$ = n2sign$ + stringmathb$: n2sign$ = ""
  100.     IF stringmathround$ <> "" THEN runningtotal$ = runningtotal$ + stringmathround$
  101.     PRINT "Validated: "; runningtotal$
  102.     IF INSTR(LCASE$(stringmathb$), "e") <> 0 THEN BEEP: GOSUB scientific_to_numeric
  103.     GOSUB validate_string_number
  104.     PRINT "Validated: "; stringmathb$
  105.     IF stringmathb$ = "invalid number" THEN EXIT SUB
  106.     IF INSTR(UCASE$(stringmathb$), "e") <> 0 THEN GOSUB scientific_to_numeric
  107. IF runningtotal$ <> "" THEN stringmatha$ = runningtotal$
  108.  
  109. SELECT CASE operator$
  110.     CASE "+", "-"
  111.         string_add_subtract:
  112.         IF INSTR(stringmatha$, ".") <> 0 THEN ' Evaluate sum for decimal fraction.
  113.             sumplace& = LEN(stringmatha$) - INSTR(stringmatha$, ".")
  114.             stringmatha$ = MID$(stringmatha$, 1, INSTR(stringmatha$, ".") - 1) + MID$(stringmatha$, INSTR(stringmatha$, ".") + 1) ' Strip out decimal
  115.         END IF
  116.         IF INSTR(stringmathb$, ".") <> 0 THEN ' Evaluate number for decimal fraction.
  117.             numplace& = LEN(stringmathb$) - INSTR(stringmathb$, ".")
  118.             stringmathb$ = MID$(stringmathb$, 1, INSTR(stringmathb$, ".") - 1) + MID$(stringmathb$, INSTR(stringmathb$, ".") + 1) ' Strip out decimal
  119.         END IF
  120.         IF sumplace& > numplace& THEN addsubplace& = sumplace& ELSE addsubplace& = numplace&
  121.         IF sumplace& > addsubplace& THEN
  122.             stringmatha$ = stringmatha$ + STRING$(sumplace& - addsubplace&, "0")
  123.         ELSEIF addsubplace& > sumplace& THEN
  124.             stringmatha$ = stringmatha$ + STRING$(addsubplace& - sumplace&, "0")
  125.         END IF
  126.         IF numplace& > addsubplace& THEN
  127.             stringmathb$ = stringmathb$ + STRING$(numplace& - addsubplace&, "0")
  128.         ELSEIF addsubplace& > numplace& THEN
  129.             stringmathb$ = stringmathb$ + STRING$(addsubplace& - numplace&, "0")
  130.         END IF ' END Decimal evaluations.
  131.  
  132.         IF LEFT$(stringmatha$, 1) = "-" THEN sign_input$ = "-" ELSE sign_input$ = "+"
  133.         IF LEFT$(stringmathb$, 1) = "-" THEN sign_total$ = "-" ELSE sign_total$ = "+"
  134.  
  135.         addsubsign% = 0
  136.         SELECT CASE sign_input$ + operator$ + sign_total$
  137.             CASE "+++", "+--"
  138.                 operator$ = "+"
  139.                 IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
  140.             CASE "++-", "+-+"
  141.                 operator$ = "-"
  142.                 IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
  143.                 IF VAL(stringmathb$) > VAL(stringmatha$) THEN SWAP stringmatha$, stringmathb$: addsubsign% = -1
  144.             CASE "---", "-++"
  145.                 operator$ = "-"
  146.                 IF LEFT$(stringmatha$, 1) = "-" THEN stringmatha$ = MID$(stringmatha$, 2)
  147.                 IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
  148.                 IF VAL(stringmathb$) > VAL(stringmatha$) THEN SWAP stringmatha$, stringmathb$ ELSE addsubsign% = -1
  149.             CASE "--+", "-+-"
  150.                 operator$ = "+"
  151.                 IF LEFT$(stringmatha$, 1) = "-" THEN stringmatha$ = MID$(stringmatha$, 2)
  152.                 IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
  153.                 addsubsign% = -1
  154.         END SELECT
  155.  
  156.         IF LEN(stringmatha$) > LEN(stringmathb$) THEN
  157.             stringmathb$ = STRING$(LEN(stringmatha$) - LEN(stringmathb$), "0") + stringmathb$
  158.         ELSEIF LEN(stringmatha$) < LEN(stringmathb$) THEN
  159.             stringmatha$ = STRING$(LEN(stringmathb$) - LEN(stringmatha$), "0") + stringmatha$
  160.         END IF
  161.         addsubx1$ = ""
  162.  
  163.         SELECT CASE operator$
  164.             CASE "+", "="
  165.                 FOR addsubii& = LEN(stringmatha$) TO 1 STEP -1
  166.                     addsubx1% = VAL(MID$(stringmatha$, addsubii&, 1)) + VAL(MID$(stringmathb$, addsubii&, 1)) + addsubcarry%
  167.                     IF addsubx1% > 9 THEN addsubx1% = addsubx1% - 10: addsubcarry% = 1 ELSE addsubcarry% = 0
  168.                     addsubx1$ = LTRIM$(STR$(addsubx1%)) + addsubx1$
  169.                 NEXT
  170.                 IF addsubcarry% THEN addsubx1$ = "1" + addsubx1$: addsubcarry% = 0
  171.                 GOSUB replace_decimal
  172.             CASE "-"
  173.                 FOR addsubii& = LEN(stringmatha$) TO 1 STEP -1
  174.                     addsubx1% = VAL(MID$(stringmatha$, addsubii&, 1)) - VAL(MID$(stringmathb$, addsubii&, 1)) + addsubcarry%
  175.                     IF addsubx1% < 0 THEN addsubx1% = addsubx1% + 10: addsubcarry% = -1 ELSE addsubcarry% = 0
  176.                     addsubx1$ = LTRIM$(STR$(addsubx1%)) + addsubx1$
  177.                 NEXT
  178.                 IF addsubx1$ <> "" AND addsubx1$ <> STRING$(LEN(addsubx1$), "0") THEN GOSUB replace_decimal
  179.                 DO UNTIL LEFT$(addsubx1$, 1) <> "0" ' Remove leading zeros.
  180.                     addsubx1$ = MID$(addsubx1$, 2)
  181.                 LOOP
  182.                 IF addsubx1$ = "" THEN
  183.                     addsubx1$ = "0": addsubsign% = 0
  184.                 ELSE
  185.                     IF addsubcarry% THEN addsubx1$ = "-" + addsubx1$: addsubcarry% = 0
  186.                 END IF
  187.         END SELECT
  188.  
  189.         IF addsubsign% THEN
  190.             IF LEFT$(addsubx1$, 1) = "-" THEN addsubx1$ = MID$(addsubx1$, 2) ELSE addsubx1$ = "-" + addsubx1$
  191.         END IF
  192.         stringmatha$ = addsubx1$: addsubx1$ = ""
  193.         IF operationdivision% THEN RETURN
  194.         stringmathb$ = stringmatha$: stringmatha$ = ""
  195.         IF LEFT$(stringmathb$, 1) = "-" THEN
  196.             stringmathb$ = MID$(stringmathb$, 2)
  197.             n2sign$ = "-"
  198.         ELSE
  199.             n2sign$ = ""
  200.         END IF
  201.         GOSUB limit_round_convert
  202.         IF stringmathb$ = "overflow" THEN n2sign$ = "": EXIT SUB
  203.         GOSUB sm_converter
  204.         runningtotal$ = n2sign$ + stringmathb$: n2sign$ = ""
  205.  
  206.     CASE "*"
  207.         string_multiply:
  208.         fac1$ = stringmatha$: fac2$ = stringmathb$ ' Make numbers whole numbers and remove any - sign.
  209.         IF LEFT$(fac1$, 1) = "-" THEN fac1$ = MID$(fac1$, 2): m_sign% = -1
  210.         IF LEFT$(fac2$, 1) = "-" THEN fac2$ = MID$(fac2$, 2): IF m_sign% THEN m_sign% = 0 ELSE m_sign% = -1
  211.         IF INSTR(fac1$, ".") <> 0 THEN m_decimal_places& = LEN(fac1$) - INSTR(fac1$, "."): fac1$ = MID$(fac1$, 1, INSTR(fac1$, ".") - 1) + MID$(fac1$, INSTR(fac1$, ".") + 1)
  212.         IF INSTR(fac2$, ".") <> 0 THEN m_decimal_places& = m_decimal_places& + LEN(fac2$) - INSTR(fac2$, "."): fac2$ = MID$(fac2$, 1, INSTR(fac2$, ".") - 1) + MID$(fac2$, INSTR(fac2$, ".") + 1)
  213.         FOR m_i& = LEN(fac2$) TO 1 STEP -1 ' Multiply each charter top and bottom.
  214.             m_k& = m_l&
  215.             m_x2$ = MID$(fac2$, m_i&, 1)
  216.             FOR m_j& = LEN(fac1$) TO 1 STEP -1
  217.                 m_x1$ = MID$(fac1$, m_j&, 1)
  218.                 IF m_product$ <> "" THEN
  219.                     m_add$ = LTRIM$(STR$(VAL(m_x1$) * VAL(m_x2$))) + STRING$(m_k&, "0")
  220.                     m_t& = 0: m_xproduct$ = "": m_carry% = 0
  221.                     DO ' Add multiplied characters together.
  222.                         m_x3$ = MID$(m_add$, LEN(m_add$) - m_t&, 1)
  223.                         m_x4$ = MID$(m_product$, LEN(m_product$) - m_t&, 1)
  224.                         IF m_x3$ = "" AND m_x4$ = "" THEN
  225.                             IF m_carry% THEN m_xproduct$ = "1" + m_xproduct$
  226.                             EXIT DO
  227.                         END IF
  228.                         m_g% = VAL(m_x3$) + VAL(m_x4$) + m_carry%
  229.                         IF m_g% >= 10 THEN m_g% = m_g% - 10: m_carry% = 1 ELSE m_carry% = 0
  230.                         m_xproduct$ = LTRIM$(STR$(m_g%)) + m_xproduct$
  231.                         m_t& = m_t& + 1
  232.                     LOOP
  233.                     m_product$ = m_xproduct$: m_xproduct$ = ""
  234.                 ELSE
  235.                     m_product$ = LTRIM$(STR$(VAL(m_x1$) * VAL(m_x2$))) + STRING$(m_k&, "0") ' First loop makes variable here.
  236.                 END IF
  237.                 m_k& = m_k& + 1 ' Adds trailing zeros multiplication
  238.             NEXT
  239.             m_l& = m_l& + 1 ' Used to reset value for m_k& adding one trailing zer for each loop.
  240.         NEXT
  241.         fac1$ = "": fac2$ = "": m_l& = 0: m_k& = 0: m_t& = 0
  242.         IF m_decimal_places& > LEN(m_product$) THEN m_product$ = STRING$(m_decimal_places& - LEN(m_product$), "0") + m_product$ ' Add any leading zeros to a decimal. Ex: .02 * .01 is factored as 002. It needs one leading zero before adding the decimal point, .0002.
  243.         IF m_decimal_places& AND m_product$ <> "0" THEN ' Replace any decimal point.
  244.             m_product$ = MID$(m_product$, 1, LEN(m_product$) - m_decimal_places&) + "." + MID$(m_product$, LEN(m_product$) - m_decimal_places& + 1)
  245.         END IF
  246.         DO UNTIL LEFT$(m_product$, 1) <> "0" ' Remove leading zeros.
  247.             m_product$ = MID$(m_product$, 2)
  248.         LOOP
  249.         IF m_decimal_places& THEN
  250.             DO UNTIL RIGHT$(m_product$, 1) <> "0" ' Remove trailing zeros in a decimal sum.
  251.                 m_product$ = MID$(m_product$, 1, LEN(m_product$) - 1)
  252.             LOOP
  253.         END IF
  254.         IF m_product$ = "" THEN m_product$ = "0": m_sign% = 0
  255.         IF RIGHT$(m_product$, 1) = "." THEN m_product$ = MID$(m_product$, 1, LEN(m_product$) - 1) ' Remove decimal from the end of an integer total.
  256.         IF operationdivision% THEN m_sign% = 0: RETURN
  257.         stringmathb$ = m_product$: m_product$ = "": GOSUB limit_round_convert
  258.         IF stringmathb$ = "overflow" THEN EXIT SUB
  259.         GOSUB sm_converter
  260.         runningtotal$ = stringmathb$: stringmathb$ = ""
  261.         IF m_sign% THEN runningtotal$ = "-" + runningtotal$: m_sign% = 0
  262.  
  263.     CASE "/"
  264.         operationdivision% = -1
  265.         divbuffer& = LEN(stringmathb$) - LEN(stringmatha$)
  266.         IF divbuffer& < 0 THEN divbuffer& = 0
  267.         d2dividend$ = stringmatha$
  268.         d1divisor$ = stringmathb$
  269.         IF LEFT$(d1divisor$, 1) = "0" AND LEN(d1divisor$) = 1 THEN PRINT "Division by zero not allowed.": END
  270.         IF LEFT$(d1divisor$, 1) = "-" THEN divsign% = -1: d1divisor$ = MID$(d1divisor$, 2)
  271.         IF LEFT$(d2dividend$, 1) = "-" THEN
  272.             IF divsign% THEN
  273.                 divsign% = 0
  274.             ELSE
  275.                 divsign% = -1
  276.             END IF
  277.             d2dividend$ = MID$(d2dividend$, 2)
  278.         END IF
  279.         IF INSTR(d1divisor$, ".") <> 0 THEN
  280.             DO UNTIL RIGHT$(d1divisor$, 1) <> "0"
  281.                 d1divisor$ = MID$(d1divisor$, 1, LEN(d1divisor$) - 1) ' Strip off trailing zeros
  282.             LOOP
  283.             divplace& = LEN(d1divisor$) - INSTR(d1divisor$, ".")
  284.             d1divisor$ = MID$(d1divisor$, 1, INSTR(d1divisor$, ".") - 1) + MID$(d1divisor$, INSTR(d1divisor$, ".") + 1) ' Strip off decimal point.
  285.             DO UNTIL LEFT$(d1divisor$, 1) <> "0"
  286.                 d1divisor$ = MID$(d1divisor$, 2) ' Strip off leading zeros for divisors smaller than .1
  287.             LOOP
  288.         END IF
  289.  
  290.         IF INSTR(d2dividend$, ".") <> 0 THEN
  291.             d2dividend$ = d2dividend$ + STRING$(divplace& - LEN(d2dividend$) - INSTR(d2dividend$, "."), "0") ' Add any zeros based on the length of dividend at decimal - length of divisor at decimal. If less than zero, nothing added.
  292.             divplace2& = INSTR(d2dividend$, ".")
  293.             DO UNTIL RIGHT$(d2dividend$, 1) <> "0"
  294.                 d2dividend$ = MID$(d2dividend$, 1, LEN(d2dividend$) - 1) ' Strip off trailing zeros
  295.             LOOP
  296.             d2dividend$ = MID$(d2dividend$, 1, INSTR(d2dividend$, ".") - 1) + MID$(d2dividend$, INSTR(d2dividend$, ".") + 1) ' Strip off decimal point.
  297.         ELSE
  298.             d2dividend$ = d2dividend$ + STRING$(divplace&, "0") ' Add any zeros based on the length of dividend at decimal - length of divisor at decimal. If less than zero, nothing added.
  299.             divplace& = 0
  300.         END IF
  301.         DO
  302.             DO
  303.                 divremainder& = divremainder& + 1: divremainder$ = divremainder$ + MID$(d2dividend$, divremainder&, 1)
  304.                 IF MID$(d2dividend$, divremainder&, 1) = "" THEN
  305.                     IF divremainder$ = STRING$(LEN(divremainder$), "0") AND LEN(quotient$) > LEN(d2dividend$) THEN divflag% = -1: EXIT DO
  306.                     divcarry& = divcarry& + 1
  307.                     IF divcarry& = 1 THEN divplace3& = divremainder& - 1
  308.                     IF divcarry& > limit&& + 1 + divbuffer& THEN
  309.                         divflag% = -2: EXIT DO
  310.                     END IF
  311.                     divremainder$ = divremainder$ + "0" ' No more digits to bring down.
  312.                 END IF
  313.                 IF LEN(divremainder$) > LEN(d1divisor$) OR LEN(divremainder$) = LEN(d1divisor$) AND divremainder$ >= d1divisor$ THEN EXIT DO
  314.                 quotient$ = quotient$ + "0"
  315.             LOOP
  316.             IF divflag% THEN divflag% = 0: EXIT DO
  317.             FOR div_i% = 9 TO 1 STEP -1
  318.                 stringmatha$ = LTRIM$(STR$(div_i%)): stringmathb$ = d1divisor$
  319.                 m_product$ = "": GOSUB string_multiply
  320.                 tempcutd$ = divremainder$ ' divremainder$ can be 00 or other leading zero values.
  321.                 DO
  322.                     IF LEN(tempcutd$) = 1 THEN EXIT DO
  323.                     IF LEFT$(tempcutd$, 1) = "0" THEN
  324.                         tempcutd$ = MID$(tempcutd$, 2)
  325.                     ELSE
  326.                         EXIT DO
  327.                     END IF
  328.                 LOOP
  329.                 IF LEN(tempcutd$) > LEN(m_product$) OR LEN(tempcutd$) = LEN(m_product$) AND m_product$ <= tempcutd$ THEN EXIT FOR
  330.             NEXT
  331.             quotient$ = quotient$ + LTRIM$(STR$(div_i%))
  332.             stringmatha$ = LTRIM$(STR$(div_i%)): stringmathb$ = d1divisor$
  333.             m_product$ = "": GOSUB string_multiply
  334.             operator$ = "-"
  335.             stringmatha$ = divremainder$
  336.             stringmathb$ = m_product$
  337.             GOSUB string_add_subtract
  338.             divremainder$ = stringmatha$
  339.             operator$ = "/"
  340.         LOOP
  341.         IF divplace& = 0 AND divplace2& = 0 THEN divplace& = divplace3&
  342.         IF divplace2& THEN divplace& = divplace& + divplace2& - 1
  343.         IF quotient$ = "" THEN divplace& = 0 ' dividend is zero.
  344.         IF divplace& OR divplace2& THEN
  345.             quotient$ = MID$(quotient$, 1, divplace&) + "." + MID$(quotient$, divplace& + 1)
  346.             DO UNTIL RIGHT$(quotient$, 1) <> "0"
  347.                 quotient$ = MID$(quotient$, 1, LEN(quotient$) - 1) ' Strip off trailing zeros
  348.             LOOP
  349.             IF RIGHT$(quotient$, 1) = "." THEN quotient$ = MID$(quotient$, 1, LEN(quotient$) - 1) ' Strip off abandoned decimal.
  350.         END IF
  351.         DO UNTIL LEFT$(quotient$, 1) <> "0"
  352.             quotient$ = MID$(quotient$, 2) ' Strip off leading zeros
  353.         LOOP
  354.         IF quotient$ = "" THEN quotient$ = "0": divsign% = 0
  355.         operationdivision% = 0
  356.         stringmathb$ = quotient$: quotient$ = "": GOSUB limit_round_convert
  357.         IF stringmathb$ = "overflow" THEN divsign% = 0: EXIT SUB
  358.         GOSUB sm_converter
  359.         runningtotal$ = stringmathb$: stringmathb$ = ""
  360.         IF divsign% THEN runningtotal$ = "-" + runningtotal$
  361. IF stringmathround$ <> "" THEN runningtotal$ = runningtotal$ + stringmathround$
  362.  
  363. validate_string_number:
  364. vsn_negcnt& = 0: vsn_poscnt& = 0: vsn_depresent& = 0: decimalcnt& = 0: vsn_numberpresent& = 0: vsn_zerospresent& = 0
  365. IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2): sm_sign$ = "-" ELSE sm_sign$ = ""
  366. IF LEFT$(stringmathb$, 1) = "+" THEN IF sm_sign$ <> "-" THEN stringmathb$ = MID$(stringmathb$, 2) ELSE stringmathb$ = "invalid number": RETURN
  367. IF INSTR(UCASE$(stringmathb$), "D") OR INSTR(UCASE$(stringmathb$), "E") THEN ' Evaluate for Scientific Notation.
  368.     FOR sm_i& = 1 TO LEN(stringmathb$)
  369.         validatenum$ = MID$(UCASE$(stringmathb$), sm_i&, 1)
  370.         SELECT CASE validatenum$
  371.             CASE "+"
  372.                 IF vsn_depresent& THEN vsn_poscnt& = vsn_poscnt& + 1 ELSE stringmathb$ = "invalid number": RETURN
  373.             CASE "-"
  374.                 IF vsn_depresent& THEN vsn_negcnt& = vsn_negcnt& + 1 ELSE stringmathb$ = "invalid number": RETURN
  375.             CASE "0" TO "9"
  376.                 vsn_numberpresent& = -1
  377.             CASE "D", "E"
  378.                 vsn_depresent& = vsn_depresent& + 1
  379.                 IF decimalcnt& = 0 AND sm_i& <> 2 OR vsn_depresent& > 1 OR vsn_numberpresent& = 0 OR vsn_negcnt& > 1 OR vsn_poscnt& > 1 OR vsn_negcnt& = 1 AND vsn_poscnt& >= 1 THEN vsn_numberpresent& = 0: EXIT FOR
  380.                 vsn_numberpresent& = 0
  381.                 MID$(stringmathb$, sm_i&, 1) = "e" ' Standardize
  382.             CASE "."
  383.                 decimalcnt& = decimalcnt& + 1
  384.                 IF sm_i& <> 2 THEN vsn_numberpresent& = 0: EXIT FOR
  385.             CASE ELSE
  386.                 vsn_numberpresent& = 0: EXIT FOR
  387.         END SELECT
  388.     NEXT
  389.     IF decimalcnt& = 0 THEN stringmathb$ = MID$(stringmathb$, 1, 1) + "." + MID$(stringmathb$, 2) ' Standardize "."
  390.     IF vsn_numberpresent& = 0 OR vsn_negcnt& = 1 AND vsn_poscnt& = 1 OR decimalcnt& > 1 OR INSTR(stringmathb$, ".") <> 2 THEN stringmathb$ = "invalid number": RETURN
  391.     vsn_depresent& = INSTR(stringmathb$, "e")
  392.     sm_x$ = MID$(stringmathb$, vsn_depresent& + 1, 1) ' Standardize exponent "+" these two lines.
  393.     IF sm_x$ <> "+" AND sm_x$ <> "-" THEN stringmathb$ = MID$(stringmathb$, 1, vsn_depresent&) + "+" + MID$(stringmathb$, vsn_depresent& + 1)
  394.     IF MID$(stringmathb$, vsn_depresent& + 2, 1) = "0" THEN
  395.         IF MID$(stringmathb$, vsn_depresent& + 3, 1) <> "" THEN stringmathb$ = "invalid number": RETURN ' No leading zeros allowed in exponent notation.
  396.     END IF
  397.     jjed& = INSTR(stringmathb$, "e") ' Get position of notation.
  398.     valexpside$ = MID$(stringmathb$, jjed&) ' These two lines break up into number and notation
  399.     stringmathb$ = MID$(stringmathb$, 1, jjed& - 1) ' stringmathb$ is +- single digit whole number, decimal point and decimal number. valexpside$ is notation, sign and exponent.
  400.     DO UNTIL RIGHT$(stringmathb$, 1) <> "0" ' Remove any trailing zeros for number. Example 1.0d3 or 1.0000d3, etc.
  401.         stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1)
  402.     LOOP
  403.     IF VAL(MID$(stringmathb$, 1, INSTR(stringmathb$, ".") - 1)) = 0 THEN
  404.         IF RIGHT$(stringmathb$, 1) = "." THEN
  405.             stringmathb$ = "0.e+0" ' Handles all types of zero entries.
  406.         ELSE
  407.             stringmathb$ = "invalid number": RETURN
  408.         END IF
  409.         RETURN
  410.     END IF
  411.     stringmathb$ = sm_sign$ + stringmathb$ + valexpside$
  412.     RETURN
  413.     FOR sm_i& = 1 TO LEN(stringmathb$)
  414.         validatenum$ = MID$(stringmathb$, sm_i&, 1)
  415.         SELECT CASE validatenum$
  416.             CASE "."
  417.                 decimalcnt& = decimalcnt& + 1
  418.             CASE "0"
  419.                 vsn_zerospresent& = -1
  420.             CASE "1" TO "9"
  421.                 vsn_numberpresent& = -1
  422.             CASE "$"
  423.             CASE ELSE
  424.                 stringmathb$ = "invalid number": RETURN
  425.         END SELECT
  426.     NEXT
  427.     IF decimalcnt& > 1 OR vsn_negcnt& > 1 OR vsn_poscnt& > 1 OR vsn_negcnt& >= 1 AND vsn_poscnt& >= 1 THEN
  428.         stringmathb$ = "invalid number": RETURN
  429.     END IF
  430.     IF INSTR(stringmathb$, "$") THEN GOSUB currency_validate
  431.     IF INSTR(stringmathb$, ",") THEN
  432.         GOSUB comma_validation
  433.         IF stringmathb$ = "invalid number" THEN RETURN
  434.         GOSUB comma_removal
  435.     END IF
  436.     IF RIGHT$(stringmathb$, 1) = "." THEN stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1)
  437.     DO UNTIL LEFT$(stringmathb$, 1) <> "0" ' Strip off any leading zeros.
  438.         stringmathb$ = MID$(stringmathb$, 2)
  439.     LOOP
  440.     stringmathb$ = sm_sign$ + stringmathb$
  441.     IF INSTR(stringmathb$, ".") THEN
  442.         DO UNTIL RIGHT$(stringmathb$, 1) <> "0" ' Strip off any trailing zeros in a decimal.
  443.             stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1)
  444.         LOOP
  445.     END IF
  446.     IF RIGHT$(stringmathb$, 1) = "." THEN stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1)
  447.     IF vsn_numberpresent& = 0 THEN
  448.         IF vsn_zerospresent& THEN
  449.             stringmathb$ = "0"
  450.         ELSE
  451.             stringmathb$ = "invalid number"
  452.         END IF
  453.     END IF
  454.  
  455. ' Convert to commas, currency, S.N., etc.
  456. sm_converter:
  457. IF comma_display% THEN GOSUB comma_placement
  458. IF currency_display% THEN GOSUB currency_convert
  459. IF snconvert% THEN GOSUB numeric_to_scientific
  460.  
  461. ' Add in commas.
  462. comma_placement:
  463. GOSUB comma_prep
  464. sm_i& = 0: sm_j& = 0: sm_seed& = 0
  465. sm_seed& = LEN(temp_stringmathb1$) MOD 3: IF sm_seed& = 0 THEN sm_seed& = 3
  466. sm_m1& = LEN(temp_stringmathb1$)
  467. sm_m2& = (LEN(temp_stringmathb1$) - 1) \ 3
  468. sm_replace$ = SPACE$(sm_m1& + sm_m2&)
  469. DO WHILE sm_i& < sm_m1&
  470.     MID$(sm_replace$, sm_j& + 1, sm_seed& + 1) = MID$(temp_stringmathb1$, sm_i& + 1, sm_seed&) + ","
  471.     sm_i& = sm_i& + sm_seed&: sm_j& = sm_j& + sm_seed& + 1: sm_seed& = 3
  472. sm_replace$ = RTRIM$(sm_replace$)
  473. IF RIGHT$(sm_replace$, 1) = "," THEN
  474.     stringmathb$ = MID$(sm_replace$, 1, LEN(sm_replace$) - 1)
  475.     stringmathb$ = sm_replace$
  476. sm_replace$ = "": temp_stringmathb1$ = ""
  477.  
  478. ' Validate comma entry.
  479. comma_validation:
  480. GOSUB comma_prep
  481. IF INSTR(temp_stringmathb2$, ",") <> 0 OR temp_stringmathb1$ = STRING$(LEN(temp_stringmathb1$), ",") THEN
  482.     stringmathb$ = "invalid number" ' Decimal part has comma or entry is all commas.
  483.     FOR sm_i& = LEN(temp_stringmathb1$) TO 1 STEP -1
  484.         sm_j% = sm_j% + 1
  485.         IF sm_j% = 4 THEN
  486.             IF MID$(temp_stringmathb1$, sm_i&, 1) <> "," THEN stringmathb$ = "invalid number": EXIT FOR
  487.             sm_j% = 0
  488.         END IF
  489.     NEXT
  490.     IF stringmathb$ <> "invalid number" THEN
  491.         stringmathb$ = sm_sign$ + temp_stringmathb1$ + temp_stringmathb2$
  492.     END IF
  493. temp_stringmathb1$ = "": temp_stringmathb2$ = "": sm_i& = 0: sm_j% = 0: sm_sign$ = "": sm_dollar$ = ""
  494.  
  495. comma_removal:
  496. sm_i& = 0: sm_j& = 0: sm_seed& = 0
  497. sm_replace$ = SPACE$(LEN(stringmathb$))
  498.     sm_i& = INSTR(sm_seed& + 1, stringmathb$, ",")
  499.     IF sm_i& = 0 THEN EXIT DO
  500.     MID$(sm_replace$, sm_j& + 1, sm_i& - sm_seed& + 1) = MID$(stringmathb$, sm_seed& + 1, sm_i& - sm_seed& - 1)
  501.     sm_j& = sm_j& + sm_i& - sm_seed& - 1
  502.     sm_seed& = sm_i&
  503. stringmathb$ = RTRIM$(sm_replace$) + MID$(stringmathb$, sm_seed& + 1): sm_replace$ = ""
  504.  
  505. comma_prep:
  506. IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2): sm_sign$ = "-"
  507. temp_stringmathb1$ = stringmathb$: stringmathb$ = ""
  508. IF INSTR(temp_stringmathb1$, ".") THEN
  509.     temp_stringmathb2$ = MID$(temp_stringmathb1$, INSTR(temp_stringmathb1$, ".")) ' Decimal part
  510.     temp_stringmathb1$ = MID$(temp_stringmathb1$, 1, INSTR(temp_stringmathb1$, ".") - 1) ' Non-decimal part
  511. IF LEFT$(temp_stringmathb1$, 1) = "$" THEN temp_stringmathb1$ = MID$(temp_stringmathb1$, 2): sm_dollar$ = "$"
  512.  
  513. currency_validate:
  514. IF LEFT$(stringmathb$, 2) = "$-" OR LEFT$(stringmathb$, 2) = "$+" THEN stringmathb$ = "invalid number": RETURN
  515. IF LEFT$(stringmathb$, 1) = "$" THEN stringmathb$ = MID$(stringmathb$, 2)
  516. IF INSTR(stringmathb$, "$") THEN stringmathb$ = "invalid number": RETURN
  517. sm_dollar$ = "$"
  518.  
  519. currency_convert:
  520. IF INSTR(UCASE$(stringmathb$), "D") <> 0 OR INSTR(UCASE$(stringmathb$), "E") <> 0 THEN GOSUB scientific_to_numeric
  521. IF INSTR(stringmathb$, ",") = 0 THEN GOSUB comma_placement
  522. IF INSTR(stringmathb$, ".") = 0 THEN stringmathb$ = stringmathb$ + ".00"
  523. IF RIGHT$(stringmathb$, 1) = "." THEN stringmathb$ = stringmathb$ + "00"
  524. IF MID$(stringmathb$, LEN(stringmathb$) - 2, 1) <> "." THEN stringmathb$ = stringmathb$ + "0"
  525. IF MID$(stringmathb$, LEN(stringmathb$) - 2, 1) <> "." THEN stringmathb$ = "invalid number": RETURN
  526. IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2)
  527. stringmathb$ = sm_sign$ + "$" + stringmathb$
  528.  
  529. numeric_to_scientific:
  530. IF LEFT$(stringmathb$, 1) = "-" THEN stringmathb$ = MID$(stringmathb$, 2): n2sign$ = "-"
  531. IF INSTR(stringmathb$, ".") = 0 THEN exponentvalue&& = LEN(stringmathb$) - 1 ELSE exponentvalue&& = INSTR(stringmathb$, ".") - 2 ' Exponent is one less than number of digits for whole number an two less than the placement of the decimal point for a fraction.
  532. stringmathb$ = MID$(stringmathb$, 1, INSTR(stringmathb$, ".") - 1) + MID$(stringmathb$, INSTR(stringmathb$, ".") + 1)
  533. IF LEFT$(stringmathb$, 1) = "0" AND LEN(stringmathb$) > 1 OR exponentvalue&& = -1 THEN
  534.     DO UNTIL LEFT$(stringmathb$, 1) <> "0" ' Remove leading zeros to consider rounding.
  535.         stringmathb$ = MID$(stringmathb$, 2)
  536.         exponentvalue&& = exponentvalue&& - 1
  537.     LOOP
  538.     esign$ = "-"
  539.     esign$ = "+"
  540. DO UNTIL RIGHT$(stringmathb$, 1) <> "0" ' Remove trailing zeros.
  541.     stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1)
  542. IF stringmathb$ = "" THEN stringmathb$ = "0": esign$ = "+": exponentvalue&& = 0
  543. stringmathb$ = LEFT$(stringmathb$, 1) + "." + MID$(stringmathb$, 2)
  544. IF stringmathb$ = "0." THEN n2sign$ = "": esign$ = "+"
  545. stringmathb$ = stringmathb$ + "e" + esign$ + LTRIM$(STR$(ABS(exponentvalue&&))) ' S.N formed here.
  546. IF stringmathb$ <> "overflow" THEN
  547.     stringmathb$ = n2sign$ + stringmathb$
  548. n2sign$ = "": esign$ = "": exponentvalue&& = 0
  549.  
  550. scientific_to_numeric:
  551. IF INSTR(UCASE$(stringmathb$), "D") THEN MID$(stringmathb$, INSTR(UCASE$(stringmathb$), "D"), 1) = "e"
  552. IF MID$(stringmathb$, INSTR(stringmathb$, "e") + 2) = "0" THEN ' The numeric value is the number without the zero exponent.
  553.     stringmathb$ = MID$(stringmathb$, 1, INSTR(stringmathb$, "e") - 1)
  554.     IF RIGHT$(stringmathb$, 1) = "." THEN stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1)
  555.     RETURN
  556.     IF LEFT$(stringmathb$, 1) = "-" THEN stn_sign$ = "-": stringmathb$ = MID$(stringmathb$, 2)
  557.     stringmathb$ = MID$(stringmathb$, 1, INSTR(stringmathb$, ".") - 1) + MID$(stringmathb$, INSTR(stringmathb$, ".") + 1) ' Remove decimal point.
  558.     stn_i& = INSTR(stringmathb$, "e") - 1 ' Length of the numric part.
  559.     IF MID$(stringmathb$, INSTR(stringmathb$, "e") + 1, 1) = "-" THEN
  560.         stringmathb$ = "." + STRING$(VAL(MID$(stringmathb$, stn_i& + 3)) - 1, "0") + MID$(stringmathb$, 1, stn_i&) ' Decimal point followed by exponent value in zeros added in front of numeric part.
  561.     ELSE
  562.         IF stn_i& - 1 > VAL(MID$(stringmathb$, stn_i& + 3)) THEN stn_point$ = "." ' - 1 for decimal place. Ex 2.034d+2 is 2034 here where 3 places to the right . could be moved before . disappears. > so no trailing decimal results.
  563.         stringmathb$ = MID$(MID$(stringmathb$, 1, stn_i&), 1, VAL(MID$(stringmathb$, stn_i& + 3)) + 1) + stn_point$ + MID$(MID$(stringmathb$, 1, stn_i&), VAL(MID$(stringmathb$, stn_i& + 3)) + 2, stn_i& - VAL(MID$(stringmathb$, stn_i& + 3)) - 1) + STRING$(VAL(MID$(stringmathb$, stn_i& + 2)) - (stn_i& - 1), "0")
  564.     END IF
  565. IF stringmathb$ = "0" THEN stn_sign$ = ""
  566. stringmathb$ = stn_sign$ + stringmathb$
  567. stn_sign$ = "": stn_point$ = ""
  568.  
  569. limit_round_convert:
  570. ' Try SN if whole number is too large (as it may be trailing zeros) or decimal is beyond limit.
  571. IF LEFT$(stringmathb$, 2) = ".0" AND LEN(stringmathb$) > limit&& + 1 OR INSTR(stringmathb$, ".") > limit&& + 1 OR INSTR(stringmathb$, ".") = 0 AND LEN(stringmathb$) > limit&& THEN
  572.     IF limit&& > 1 THEN
  573.         GOSUB numeric_to_scientific ' Retry as S.N.
  574.         IF LEN(stringmathb$) > limit&& + 3 THEN ' Needs rounding.
  575.             snotation$ = MID$(stringmathb$, INSTR(UCASE$(stringmathb$), "E"))
  576.             exponentvalue&& = VAL(MID$(snotation$, 2)) ' Get positive or negative sign.
  577.             snexponent$ = MID$(stringmathb$, INSTR(UCASE$(stringmathb$), "E") + 2)
  578.             stringmathb$ = MID$(stringmathb$, 1, INSTR(UCASE$(stringmathb$), "E") - 1)
  579.             '''IF LEN(stringmathb$) + LEN(snexponent$) > limit&& + 1 AND exponentvalue&& >= limit&& THEN BEEP
  580.             IF exponentvalue&& >= limit&& THEN
  581.                 stringmathb$ = MID$(stringmathb$, 1, exponentvalue&& + 3)
  582.             ELSE
  583.                 stringmathb$ = MID$(stringmathb$, 1, limit&& - LEN(snexponent$) + 2)
  584.             END IF
  585.             GOSUB string_rounding_method
  586.             IF LEFT$(stringmathb$, 3) = "10." THEN
  587.                 stringmathb$ = "1." + MID$(stringmathb$, 4)
  588.                 ' Add one to the exponent.
  589.                 FOR round_i& = LEN(snexponent$) TO 1 STEP -1
  590.                     round_x$ = CHR$(ASC(MID$(snexponent$, round_i&, 1)) + 1)
  591.                     IF round_x$ <> CHR$(47) THEN ' Decimal point + 1. Ignore.
  592.                         IF round_x$ = CHR$(58) THEN
  593.                             MID$(snexponent$, round_i&, 1) = "0": carry$ = "1"
  594.                         ELSE
  595.                             MID$(snexponent$, round_i&, 1) = round_x$: carry$ = "": EXIT FOR
  596.                         END IF
  597.                     END IF
  598.                 NEXT
  599.                 snexponent$ = carry$ + snexponent$: carry$ = ""
  600.             END IF
  601.             stringmathb$ = stringmathb$ + MID$(snotation$, 1, 2) + snexponent$
  602.             IF LEN(snexponent$) + LEN(MID$(stringmathb$, 1, INSTR(UCASE$(stringmathb$), "E") - 1)) > limit&& + 1 THEN
  603.                 stringmathb$ = "overflow"
  604.             END IF
  605.             exponentvalue&& = 0
  606.         END IF
  607.     ELSE
  608.         IF INSTR(stringmathb$, ".") > 0 AND INSTR(stringmathb$, ".") <= limit&& THEN
  609.             stringmathb$ = MID$(stringmathb$, 1, limit&& + 2)
  610.             IF round_total% = -1 AND RIGHT$(stringmathb$, 1) > "4" THEN
  611.                 GOSUB string_rounding_method
  612.             ELSE
  613.                 stringmathb$ = MID$(stringmathb$, 1, limit&& + 1)
  614.                 IF show_rounding% THEN stringmathround$ = "r"
  615.             END IF
  616.         ELSE
  617.             stringmathb$ = "overflow"
  618.         END IF
  619.     END IF
  620.     RETURN
  621. IF LEN(stringmathb$) > limit&& AND INSTR(stringmathb$, ".") = 0 OR LEN(stringmathb$) > limit&& + 1 AND INSTR(stringmathb$, ".") <> 0 THEN
  622.     IF INSTR(stringmathb$, ".") = 0 THEN
  623.         stringmathb$ = MID$(stringmathb$, 1, limit&& + 1)
  624.     ELSE
  625.         stringmathb$ = MID$(stringmathb$, 1, limit&& + 2)
  626.     END IF
  627.     GOSUB string_rounding_method
  628.     IF LEN(stringmathb$) > limit&& + lrc_decimalpoint& THEN ' Ex: limit&& = 4 9999.9 1.e+4
  629.         GOSUB numeric_to_scientific
  630.     ELSE
  631.         IF LEN(stringmathb$) > limit&& + lrc_decimalpoint& THEN stringmathb$ = "overflow"
  632.     END IF
  633.  
  634. replace_decimal:
  635. IF addsubplace& THEN
  636.     addsubx1$ = STRING$(addsubplace& - LEN(addsubx1$), "0") + addsubx1$
  637.     addsubx1$ = MID$(addsubx1$, 1, LEN(addsubx1$) - addsubplace&) + "." + MID$(addsubx1$, LEN(addsubx1$) - addsubplace& + 1)
  638.     DO UNTIL RIGHT$(addsubx1$, 1) <> "0" ' Remove trailing zeros in a decimal sum.
  639.         addsubx1$ = MID$(addsubx1$, 1, LEN(addsubx1$) - 1)
  640.         addsubplace& = addsubplace& - 1
  641.     LOOP
  642.     IF RIGHT$(addsubx1$, 1) = "." THEN addsubx1$ = MID$(addsubx1$, 1, LEN(addsubx1$) - 1) ' Number is now an integer.
  643.  
  644. string_rounding_method:
  645. IF INSTR(stringmathb$, ".") THEN lrc_decimalpoint& = 1 ELSE lrc_decimalpoint& = 0
  646. IF MID$(stringmathb$, LEN(stringmathb$), 1) > "4" THEN
  647.     FOR round_i& = LEN(stringmathb$) - 1 TO 1 STEP -1
  648.         round_x$ = CHR$(ASC(MID$(stringmathb$, round_i&, 1)) + 1)
  649.         IF round_x$ <> CHR$(47) THEN ' Decimal point + 1. Ignore.
  650.             IF round_x$ = CHR$(58) THEN
  651.                 MID$(stringmathb$, round_i&, 1) = "0": carry$ = "1"
  652.             ELSE
  653.                 MID$(stringmathb$, round_i&, 1) = round_x$: carry$ = "": EXIT FOR
  654.             END IF
  655.         END IF
  656.     NEXT
  657.     stringmathb$ = carry$ + MID$(stringmathb$, 1, LEN(stringmathb$) - 1): carry$ = ""
  658.     IF show_rounding% THEN stringmathround$ = "R"
  659.     stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1)
  660.     IF show_rounding% THEN stringmathround$ = "r"
  661.  
  662. IF lrc_decimalpoint& THEN
  663.     DO UNTIL RIGHT$(stringmathb$, 1) <> "0"
  664.         stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1)
  665.     LOOP
  666.     IF stringmathb$ = "" OR stringmathb$ = "." THEN stringmathb$ = "0": lrc_decimalpoint& = 0
  667.     IF RIGHT$(stringmathb$, 1) = "." AND exponentvalue&& = 0 THEN
  668.         stringmathb$ = MID$(stringmathb$, 1, LEN(stringmathb$) - 1): lrc_decimalpoint& = 0
  669.     END IF
  670.  

Pete

Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Question about number formatting
« Reply #9 on: February 19, 2021, 06:28:04 pm »
You mean something simple, like string math?

Pete

Holy cow grease, Batman! That things 1/7th the size of the main program...LOL

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Question about number formatting
« Reply #10 on: February 19, 2021, 06:57:50 pm »
Batman, Andy? More like The Green Hornet. When I was around 5 or 6, a lot of celebrities were in the area, and Adam West would come into my Dad's store. He gave him an autographed pic once, which my Dad gave to me, and I promptly tore into pieces. That was around the time the Hollywood folks were pitting Batman against the Green Hornet for an upcoming T.V. episode. Anyway... what the hell does cow grease have to do with any of this??? :D

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Question about number formatting
« Reply #11 on: February 19, 2021, 07:27:28 pm »
Quote
Anyway... what the hell does cow grease have to do with any of this??? :D

Re: Cow grease

What to use to get cows in and out when barn door won't open all the way; so you can get back to your QB64 coding faster.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Question about number formatting
« Reply #12 on: February 19, 2021, 07:51:35 pm »
Re: Cow grease

What to use to get cows in and out when barn door won't open all the way; so you can get back to your QB64 coding faster.

“Cow grease” is Bag Balm.  https://www.amazon.com/Bag-Balm-Ointment-8-Ounce/dp/B0014CI4X8/

It’s basically like medicated vaseline for a cow’s udders to help reduce/prevent cracking and chafing when milking.  :P

My question — in regard to this original topic — why even convert your figures at all?  Why not just use PRINT USING to format the display properly, and leave the figure unchanged?
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: Question about number formatting
« Reply #13 on: February 19, 2021, 08:26:47 pm »
Cow Grease is for getting your cow out of your Volvo. Don't believe me?...

https://www.cattletoday.com/threads/cow-grease.7488/

I haven't seen anything to suggest that I can shoe horn a USING into a _PRINTSTRING. I 'could' go back to LOCATE/PRINT USING, but I'm just now getting enough of a handle on _PRINTSTRING to really like it.

The glitch isn't critical for me, I just set the conversion point above where it occurs, since I have the room for 8 digit numbers. That said, I'm displaying data in small 290 x 96 images, at which point it's the odd, and out of nowhere, 23 digit {mostly 0s} exponential number; which for some reason refuses to play well with INT or _ROUND, that screws the pooch.

BTW, never use cow grease for screwin' a pooch, always use an approved pooch grease.
« Last Edit: February 19, 2021, 08:32:48 pm by OldMoses »