Author Topic: print _Float  (Read 4571 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
print _Float
« on: September 22, 2021, 01:34:40 pm »
QB64 print statement converts _Float to double so the range and precision of the output is that of double
libqb.cpp
Code: C: [Select]
  1. qbs *qbs_str(long double value){
  2.     //not fully implemented
  3.     return qbs_str((double)value);
  4. }
  5.  
here's QB64 code to help with that
Code: QB64: [Select]
  1.     Sub snprintf (Dest As String, Byval l As Long, frmt As String, Byval x As Double)
  2.  
  3.  
  4. x = 3.1415926535897932384626433832795F314
  5. Print strf(x)
  6. x = -x
  7. Print strf(x)
  8.  
  9. Function strf$ (x As _Float)
  10.     Dim As String s
  11.     Dim As String frmt
  12.     Dim As Long ex
  13.     s = Spc(64)
  14.     frmt = "%.19Lg" + Chr$(0)
  15.     Call snprintf(s, Len(s), frmt, x)
  16.     s = _Trim$(s)
  17.     ex = InStr(s, "e")
  18.     If ex > 0 Then Mid$(s, ex, 1) = "F"
  19.     If Left$(s, 1) <> "-" Then s = " " + s
  20.     strf = s
  21.  
I thought about editing qbs_str but the cpp code looks too complicated

FellippeHeitor

  • Guest
Re: print _Float
« Reply #1 on: September 22, 2021, 01:49:23 pm »
It's already a known/open issue in the repository: https://github.com/QB64Team/qb64/issues/169

Thanks for reporting.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: print _Float
« Reply #2 on: September 22, 2021, 06:00:49 pm »
You guys better grab my string math routine before I slap a million dollar price tag on it.

Pete

And I'm better looking than Bill Gates, too. But then again, so is everyone.
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: print _Float
« Reply #3 on: September 22, 2021, 07:47:42 pm »
@Pete where's the link to your string math routines ?

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: print _Float
« Reply #4 on: September 22, 2021, 09:15:13 pm »
https://www.tapatalk.com/groups/qbasic/viewtopic.php?p=212679#p212679

I think I also posted a testing version in this thread: https://www.qb64.org/forum/index.php?topic=1093.msg104230#msg104230

It was fun, but I doubt I will do much work on it in the future, to expand it to other math functions, square roots, logs etc. I should probably paste the version I have on my Win 10 into a Programs thread here.

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

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: print _Float
« Reply #5 on: September 23, 2021, 12:44:28 am »
thanks Pete, yes post the code you have now it's possible that it's tweaked for better performance

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: print _Float
« Reply #6 on: September 23, 2021, 02:19:36 pm »
I think this was what I finished on...

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.  

What I did notice is that the using comma option cuts of decimal places, unless the dollars and cents option is used, which then limits to two decimal places. Using it without showing commas in the display shows the decimal places. Looking back, I'd rather have included the decimal places with comma display. I may fiddle with that this weekend, before posting it to the programs forum.

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: print _Float
« Reply #7 on: September 24, 2021, 11:54:35 am »
What's the limit&& (in the main sub call for stringmath) ? The whole display in chars or number of decimals or ???

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: print _Float
« Reply #8 on: September 24, 2021, 02:20:14 pm »
If I recall correctly, the number of characters. If zero is entered, the default is 70.

IF limit&& = 0 THEN limit&& = 70 ' Default.

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

FellippeHeitor

  • Guest
Re: print _Float
« Reply #9 on: September 27, 2021, 09:30:24 am »
@Richard this is where the issue with PRINT and large numbers is being discussed.

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: print _Float
« Reply #10 on: September 27, 2021, 10:24:59 am »
for completeness as it seems there's a problem assigning a large literal to a _Float
Code: QB64: [Select]
  1.     Function snprintf& (Dest As String, Byval l As Long, frmt As String, Byval x As _Float)
  2.  
  3.     Sub atoldbl Alias _atoldbl (x As _Float, str As String)
  4.  
  5. Function valf## (s As String)
  6.     Dim As _Float x
  7.     Call atoldbl(x, s + Chr$(0))
  8.     valf## = x
  9.  
  10. Function strf$ (x As _Float)
  11.     Dim As String s
  12.     Dim As String frmt
  13.     Dim As Long l, ex, sign
  14.     sign = Sgn(x)
  15.     If sign < 0 Then x = -x
  16.     s = Spc(64)
  17.     frmt = "%.19Lg" + Chr$(0)
  18.     l = snprintf(s, Len(s), frmt, x)
  19.     s = _Trim$(s)
  20.     If InStr(s, ".") > 0 And Left$(s, 1) = "0" Then s = Mid$(s, 2)
  21.     If sign < 0 Then s = "-" + s Else s = " " + s
  22.     ex = InStr(s, "e")
  23.     If ex > 0 Then Mid$(s, ex, 1) = "F"
  24.     strf = s
  25.  

Marked as best answer by jack on September 27, 2021, 06:41:34 am

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: print _Float
« Reply #11 on: September 27, 2021, 10:41:20 am »
correction, there's no problem assigning a large literal to a _Float, Richard forgot to append ## to the literal
Code: QB64: [Select]
  1.     Function snprintf& (Dest As String, Byval l As Long, frmt As String, Byval x As _Float)
  2.  
  3. Screen _NewImage(768, 768, 32)
  4.  
  5. Locate 3, 1:
  6.  
  7. Color &HFF00FFFF~&&
  8. Locate , 1: Print "c##";
  9. Locate , 25: Print "c## + 1";
  10.  
  11. Color &HFFFF8000~&&
  12. Print "c## = ... :": Color &HFFFFFFFF~&&
  13. c## = 10##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  14. c## = 100##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  15. c## = 1000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  16. c## = 10000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  17. c## = 100000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  18. c## = 1000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  19. c## = 10000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  20. c## = 100000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  21. c## = 1000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  22. c## = 10000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  23. c## = 100000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  24. c## = 1000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  25. c## = 10000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  26. c## = 100000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  27. c## = 1000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  28. c## = 10000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  29. c## = 100000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  30. c## = 1000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  31. c## = 10000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  32. c## = 100000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  33. c## = 1000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  34. c## = 10000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  35. c## = 100000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  36. c## = 1000000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  37. c## = 10000000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  38. c## = 100000000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  39. c## = 1000000000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  40. c## = 10000000000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  41. c## = 100000000000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  42. c## = 1000000000000000000000000000000##: Locate , 1: Print strf(c##);: Locate , 25: Print strf(c## + 1)
  43.  
  44. Function strf$ (x As _Float)
  45.     Dim As String s
  46.     Dim As String frmt
  47.     Dim As Long l, ex, sign
  48.     sign = Sgn(x)
  49.     If sign < 0 Then x = -x
  50.     s = Spc(64)
  51.     frmt = "%.19Lg" + Chr$(0)
  52.     l = snprintf(s, Len(s), frmt, x)
  53.     s = _Trim$(s)
  54.     If InStr(s, ".") > 0 And Left$(s, 1) = "0" Then s = Mid$(s, 2)
  55.     If sign < 0 Then s = "-" + s Else s = " " + s
  56.     ex = InStr(s, "e")
  57.     If ex > 0 Then Mid$(s, ex, 1) = "F"
  58.     strf = s
  59.  
I am out of here

Offline Richard

  • Seasoned Forum Regular
  • Posts: 364
    • View Profile
Re: print _Float
« Reply #12 on: September 27, 2021, 12:02:45 pm »
@jack   Many thanks for the fix (it looks so clear now) - maybe I am pushing the _FLOAT stuff too hard and too quickly (and making silly mistakes along the way) - to me _DOUBLE stuff is way too limited (in my opinion).

-