Author Topic: Rounding up to n decimal places?  (Read 4069 times)

0 Members and 1 Guest are viewing this topic.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Rounding up to n decimal places?
« on: February 04, 2021, 02:10:23 pm »
I'm trying to figure out how to round numbers (single or double precision) up to a certain number of decimal places.
For example 0.035 rounded to 2 places should be 0.04.

I did some searching on the forums for how to round,
and found examples with INT and division, like:
INT(number * 100)/100

where you just use a number with the number of zeros you want in place of 100.
I made a test program (below) to test this,
but that method seems to just truncate down to the given number of places.

How would you round up?

Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' Rounding test
  3. ' ################################################################################################################################################################
  4.  
  5. ' a$=string, i%=integer, L&=long, s!=single, d#=double
  6.  
  7. ' BOOLEAN CONSTANTS
  8. CONST FALSE = 0
  9. CONST TRUE = NOT FALSE
  10.  
  11. ' GLOBAL VARIABLES
  12. DIM ProgramPath$
  13. DIM ProgramName$
  14. ProgramName$ = MID$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\") + 1)
  15. ProgramPath$ = LEFT$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\"))
  16.  
  17. ' START THE MAIN PROGRAM
  18. main ProgramName$
  19.  
  20. ' FINISH UP
  21. SYSTEM ' return control to the operating system
  22. PRINT ProgramName$ + " finished."
  23.  
  24. ' /////////////////////////////////////////////////////////////////////////////
  25. ' Rounding and math.
  26. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_PHPSESSID_gulg2aoa966472fnfhjkgp4i35_topic_14266-0/
  27. '
  28. ' Any number x can be rounded to n digits:
  29. '   roundedValue = INT(x*10^n + 0.5) / 10^n
  30. ' for scientific rounding you use:
  31. '   roundedValue = CINT(x*10^n) / 10^n
  32. ' Difference between Normal and Scientific Rounding:
  33. '   Normal     Rounds digits 1,2,3, and 4 down.
  34. '              Rounds digits 5,6,7,8, and 9 up.
  35. '   Scientific Rounds digits 1,2,3, and 4 down.
  36. '              Rounds digiits 6,7, 8, and 9 up.
  37. '              Rounds 5 to the nearest even number.
  38.  
  39. ' Quote from: SMcNeill on May 16, 2017, 06:57:17 pm
  40. ' Can also try:
  41. '     INT(number * 100)/100
  42. ' Now that worked.
  43. '     STR$(INT(myprice * 100) / 100)
  44. ' Perfectly drops all the numbers to 2 decimal places.
  45. ' What a relief. Thank you so much and everyone else who gave advice. :)
  46.  
  47. SUB main (ProgName$)
  48.     DIM RoutineName AS STRING:: RoutineName = "main"
  49.     DIM in$
  50.  
  51.     DIM arrOutput(100, 2) AS STRING ' arrOutput(line#, column#)
  52.     DIM s1! ' original value
  53.     DIM s2! ' rounded value
  54.     DIM d1# ' original value
  55.     DIM d2# ' rounded value
  56.     DIM iLine1 AS INTEGER ' # output lines column 1 (single)
  57.     DIM iLine2 AS INTEGER ' # output lines column 2 (double)
  58.     DIM iColumn AS INTEGER ' which column # to output to
  59.     DIM iMaxLines AS INTEGER ' # of output lines (whichever is biggest)
  60.  
  61.     CLS
  62.     iMaxLines = 0
  63.     PRINT "This code truncates or rounds down."
  64.     PRINT "How do we round _UP_ to a given # of decimal places?"
  65.     PRINT "eg. rounding 0.308 to 2 places should output 0.31"
  66.     PRINT
  67.  
  68.     ' ROUND SINGLE PRECISION NUMBERS TO 2 DECIMAL PLACES
  69.     iColumn = 1
  70.     iLine1 = 1: arrOutput(iLine1, iColumn) = "SINGLE TO 2 DECIMAL PLACES"
  71.     iLine1 = 2: arrOutput(iLine1, iColumn) = RightPadString$("Original", 10, " ") + "    " + RightPadString$("Rounded", 10, " ")
  72.     FOR s1! = 0.3 TO 0.4 STEP 0.008
  73.         iLine1 = iLine1 + 1
  74.         s2! = INT(s1! * 100) / 100
  75.         arrOutput(iLine1, iColumn) = RightPadString$(cstr$(s1!), 10, " ") + " -> " + RightPadString$(cstr$(s2!), 10, " ")
  76.     NEXT s1!
  77.     iMaxLines = iLine1
  78.  
  79.     ' ROUND DOUBLE PRECISION NUMBERS TO 3 DECIMAL PLACES
  80.     iColumn = 2
  81.     iLine2 = 1: arrOutput(iLine2, iColumn) = "DOUBLE TO 3 DECIMAL PLACES"
  82.     iLine2 = 2: arrOutput(iLine2, iColumn) = RightPadString$("Original", 10, " ") + "    " + RightPadString$("Rounded", 10, " ")
  83.     FOR d1# = 0.03 TO 0.04 STEP 0.0008
  84.         iLine2 = iLine2 + 1
  85.         d2# = INT(d1# * 1000) / 1000
  86.         arrOutput(iLine2, iColumn) = RightPadString$(cstr$(d1#), 10, " ") + " -> " + RightPadString$(cstr$(d2#), 10, " ")
  87.         IF iLine2 > iLine1 THEN
  88.             iMaxLines = iLine2
  89.             arrOutput(iLine2, 1) = ""
  90.         END IF
  91.     NEXT d1#
  92.    
  93.     ' SHOW OUTPUT
  94.     FOR iLine1 = 1 TO iMaxLines
  95.         PRINT RightPadString$(arrOutput(iLine1, 1), 30, " ") + "    " + RightPadString$(arrOutput(iLine1, 2), 30, " ")
  96.     NEXT iLine1
  97.  
  98.     PRINT
  99.     INPUT "PRESS <ENTER> TO CONTINUE", in$
  100. END SUB ' main
  101.  
  102. ' /////////////////////////////////////////////////////////////////////////////
  103.  
  104. FUNCTION RightPadString$ (myString$, toWidth%, padChar$)
  105.     RightPadString$ = LEFT$(myString$ + STRING$(toWidth%, padChar$), toWidth%)
  106. END FUNCTION ' RightPadString$
  107.  
  108. ' /////////////////////////////////////////////////////////////////////////////
  109.  
  110. FUNCTION cstr$ (myValue)
  111.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  112.     cstr$ = _TRIM$(STR$(myValue))
  113. END FUNCTION ' cstr$
  114.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Rounding up to n decimal places?
« Reply #1 on: February 04, 2021, 02:13:29 pm »
There is round Keyword check Wiki, might be _round

I have this but for rounding you have to add 1/2 of 10 ^ DP to x so better copy x before you change in function and it is passed back changed:
Code: QB64: [Select]
  1. FUNCTION xDP$ (x, DP)
  2.     DIM test$, p AS LONG
  3.     test$ = _TRIM$(STR$(INT(x * 10 ^ DP) / 10 ^ DP))
  4.     p = INSTR(test$, ".")
  5.     IF p = 0 AND DP <> 0 THEN test$ = test$ + "." + STRING$(DP, "0")
  6.     IF p AND DP = 0 THEN test$ = LEFT$(test$, LEN(test$) - 1)
  7.     xDP$ = test$
  8.  

Untested (gotta go soon):
Code: QB64: [Select]
  1. 'just cut the decimal places down to DP amount if more
  2. FUNCTION xDP$ (xx, DP)
  3.     DIM test$, p AS LONG, x
  4.     x = xx + .5 * 1/(10 ^ DP)
  5.     test$ = _TRIM$(STR$(INT(x * 10 ^ DP) / 10 ^ DP))
  6.     p = INSTR(test$, ".")
  7.     IF p = 0 AND DP <> 0 THEN test$ = test$ + "." + STRING$(DP, "0")
  8.     IF p AND DP = 0 THEN test$ = LEFT$(test$, LEN(test$) - 1)
  9.     xDP$ = test$
  10.  

EDIT: crap it's .5 * (1/10^DP)
« Last Edit: February 04, 2021, 02:29:47 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Rounding up to n decimal places?
« Reply #2 on: February 04, 2021, 02:35:15 pm »
Dang cant quit now, this is looking OK so far:
Code: QB64: [Select]
  1.     INPUT "Number to round "; n
  2.     INPUT "Number of decimal places "; dp
  3.     PRINT xDP$(n, dp)
  4. FUNCTION xDP$ (xx, DP)
  5.     DIM test$, p AS LONG, x
  6.     x = xx + .5 * 1 / (10 ^ DP)
  7.     test$ = _TRIM$(STR$(INT(x * 10 ^ DP) / 10 ^ DP))
  8.     p = INSTR(test$, ".")
  9.     IF p = 0 AND DP <> 0 THEN test$ = test$ + "." + STRING$(DP, "0")
  10.     IF p AND DP = 0 THEN test$ = LEFT$(test$, LEN(test$) - 1)
  11.     xDP$ = test$
  12.  

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Rounding up to n decimal places?
« Reply #3 on: February 04, 2021, 02:57:27 pm »
You could string round...

Code: QB64: [Select]
  1. INPUT "a number: "; num
  2. n$ = LTRIM$(STR$(num))
  3. IF INSTR(n$, ".") AND RIGHT$(n$, 1) <> "." THEN
  4.     IF RIGHT$(n$, 1) >= "5" THEN ' round up
  5.         c$ = LTRIM$(STR$(10 - VAL(MID$(n$, LEN(n$), 1))))
  6.         FOR i = LEN(n$) TO 1 STEP -1
  7.             IF MID$(n$, i, 1) >= "0" AND MID$(n$, i, 1) <= "9" THEN
  8.                 x = VAL(c$) + VAL(MID$(n$, i, 1))
  9.                 IF x > 9 THEN x = x - 10: c$ = "1" ELSE c$ = ""
  10.                 MID$(n$, i, 1) = LTRIM$(STR$(x))
  11.                 IF c$ = "" THEN EXIT FOR
  12.             END IF
  13.         NEXT
  14.     END IF
  15.  
  16.     num = VAL(c$ + n$)
  17.  
  18. PRINT num
  19.  
  20.  

Now that's on the fly, and not from my string number routine. I'm so old, I can't even tell you if it's the same method or not, but it's more fun to code than it is to paste. If anyone finds a flaw in the above, let me know. I'm not sure it's bullet proof. I can tell you I didn't bother bullet proofing for bad input.

Pete
« Last Edit: February 04, 2021, 03:05:24 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Rounding up to n decimal places?
« Reply #4 on: February 04, 2021, 03:53:48 pm »
Sometimes, you guys make things entirely too  complicated.

Code: QB64: [Select]
  1. PRINT Round(4.2345, 2)
  2. PRINT Round(4.2345, 3)
  3. PRINT RoundUp(4.2345, 2)
  4. PRINT RoundUp(4.2345, 3)
  5. PRINT RoundDown(4.2345, 2)
  6. PRINT RoundDown(4.2345, 3)
  7.  
  8. PRINT Round_Scientific(4.205, 2)
  9. PRINT Round_Scientific(4.215, 2)
  10. PRINT Round_Scientific(4.225, 2)
  11. PRINT Round_Scientific(4.235, 2)
  12. PRINT Round_Scientific(4.245, 2)
  13.  
  14. FUNCTION Round## (num##, digits%)
  15.     Round## = INT(num## * 10 ^ digits% + .5) / 10 ^ digits%
  16.  
  17. FUNCTION RoundUp## (num##, digits%)
  18.     RoundUp## = _CEIL(num## * 10 ^ digits%) / 10 ^ digits%
  19.  
  20. FUNCTION RoundDown## (num##, digits%)
  21.     RoundDown## = INT(num## * 10 ^ digits%) / 10 ^ digits%
  22.  
  23. FUNCTION Round_Scientific## (num##, digits%)
  24.     Round_Scientific## = _ROUND(num## * 10 ^ digits%) / 10 ^ digits%

There ya go!  Three functions to either round naturally (0 - 0.4999999999999999999999 rounds down, 0.5 - 0.99999999999999999 rounds up), always round down, or always round up, to whatever number of digits you desire.

EDIT:  Modified to add another option to round scientific, since you had it's description included in your example.
« Last Edit: February 04, 2021, 04:09:30 pm by SMcNeill »
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: Rounding up to n decimal places?
« Reply #5 on: February 04, 2021, 04:55:38 pm »
Quote
Sometimes, you guys make things entirely too  complicated.

Yeah, yeah, I was looking over that code of mine and going yuck myself. I think I would like to see 0's out to decimal places instead of nothing.



Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Rounding up to n decimal places?
« Reply #6 on: February 04, 2021, 05:06:52 pm »
Yeah, yeah, I was looking over that code of mine and going yuck myself. I think I would like to see 0's out to decimal places instead of nothing.

That's a job for formatting and printing at display time, not calculation time.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: Rounding up to n decimal places?
« Reply #7 on: February 04, 2021, 06:38:57 pm »
you have to add 1/2 of 10 ^ DP to x
...
EDIT: crap it's .5 * (1/10^DP)

I think I got it - thanks!

Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' Rounding test
  3. ' ################################################################################################################################################################
  4.  
  5. ' BOOLEAN CONSTANTS
  6. CONST FALSE = 0
  7. CONST TRUE = NOT FALSE
  8.  
  9. ' GLOBAL VARIABLES a$=string, i%=integer, L&=long, s!=single, d#=double
  10. DIM ProgramPath$: ProgramPath$ = LEFT$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\"))
  11. DIM ProgramName$: ProgramName$ = MID$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\") + 1)
  12.  
  13. ' START THE MAIN PROGRAM
  14. main ProgramName$
  15.  
  16. ' FINISH UP
  17. SYSTEM ' return control to the operating system
  18. PRINT ProgramName$ + " finished."
  19.  
  20. ' /////////////////////////////////////////////////////////////////////////////
  21. ' Rounding and math.
  22. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_PHPSESSID_gulg2aoa966472fnfhjkgp4i35_topic_14266-0/
  23. '
  24. ' Rounding up to n decimal places?
  25. ' https://www.qb64.org/forum/index.php?topic=3605.0
  26.  
  27. ' Quote from: SMcNeill on May 16, 2017, 06:57:17 pm
  28. ' Can also try:
  29. '     INT(number * 100)/100
  30. ' Now that worked.
  31. '     STR$(INT(myprice * 100) / 100)
  32. ' Perfectly drops all the numbers to 2 decimal places.
  33. ' What a relief. Thank you so much and everyone else who gave advice. :)
  34.  
  35. ' Quote from: bplus on Today at 02:13:29 PM
  36. ' There is round Keyword check Wiki, might be _round
  37. ' you have to add 1/2 of 10 ^ DP to x
  38. ' EDIT: crap it's .5 * (1/10^DP)
  39.  
  40. SUB main (ProgName$)
  41.     DIM RoutineName AS STRING:: RoutineName = "main"
  42.     DIM in$
  43.  
  44.     DIM arrOutput(100, 2) AS STRING
  45.     DIM s1!
  46.     DIM s2!
  47.     DIM d1#
  48.     DIM d2#
  49.     DIM iLine1 AS INTEGER
  50.     DIM iLine2 AS INTEGER
  51.     DIM iColumn AS INTEGER
  52.     DIM iMaxLines AS INTEGER
  53.     DIM dp% ' # decimal places
  54.  
  55.     CLS
  56.     iTotal = 0
  57.     PRINT "Rounds single and double precision numbers."
  58.     PRINT "Thanks to SMcNeill, bplus, and Pete for your help."
  59.     PRINT
  60.  
  61.     ' ROUND SINGLE PRECISION NUMBERS TO 3 DECIMAL PLACES
  62.     iColumn = 1
  63.     iLine1 = 1: arrOutput(iLine1, iColumn) = "SINGLE TO 3 DECIMAL PLACES"
  64.     iLine1 = 2: arrOutput(iLine1, iColumn) = RightPadString$("Original", 10, " ") + "    " + RightPadString$("Rounded", 10, " ")
  65.     dp% = 3
  66.     FOR s1! = 0.3 TO 0.4 STEP 0.008
  67.         iLine1 = iLine1 + 1
  68.         s2! = s1! + (.5 * (1 / (10 ^ dp%)))
  69.         s2! = INT(s2! * (10 ^ dp%)) / (10 ^ dp%)
  70.         arrOutput(iLine1, iColumn) = RightPadString$(SngToStr$(s1!), 10, " ") + " -> " + RightPadString$(SngToStr$(s2!), 10, " ")
  71.     NEXT s1!
  72.     iMaxLines = iLine1
  73.  
  74.     ' ROUND DOUBLE PRECISION NUMBERS TO 3 DECIMAL PLACES
  75.     iColumn = 2
  76.     iLine2 = 1: arrOutput(iLine2, iColumn) = "DOUBLE TO 3 DECIMAL PLACES"
  77.     iLine2 = 2: arrOutput(iLine2, iColumn) = RightPadString$("Original", 10, " ") + "    " + RightPadString$("Rounded", 10, " ")
  78.     dp% = 3
  79.     FOR d1# = 0.03 TO 0.04 STEP 0.0008
  80.         iLine2 = iLine2 + 1
  81.         d2# = d1# + (.5 * (1 / (10 ^ dp%)))
  82.         d2# = INT(d2# * (10 ^ dp%)) / (10 ^ dp%)
  83.         arrOutput(iLine2, iColumn) = RightPadString$(DblToStr$(d1#), 10, " ") + " -> " + RightPadString$(DblToStr$(d2#), 10, " ")
  84.  
  85.         IF iLine2 > iLine1 THEN
  86.             iMaxLines = iLine2
  87.             arrOutput(iLine2, 1) = ""
  88.         END IF
  89.     NEXT d1#
  90.  
  91.     FOR iLine1 = 1 TO iMaxLines
  92.         PRINT RightPadString$(arrOutput(iLine1, 1), 30, " ") + "    " + RightPadString$(arrOutput(iLine1, 2), 30, " ")
  93.     NEXT iLine1
  94.  
  95.     PRINT
  96.     INPUT "PRESS <ENTER> TO CONTINUE", in$
  97. END SUB ' main
  98.  
  99. ' /////////////////////////////////////////////////////////////////////////////
  100. ' Scientific notation - QB64 Wiki
  101. ' https://www.qb64.org/wiki/Scientific_notation
  102.  
  103. ' Example: A string function that displays extremely small or large exponential decimal values.
  104.  
  105. FUNCTION DblToStr$ (n#)
  106.     value$ = UCASE$(LTRIM$(STR$(n#)))
  107.     Xpos% = INSTR(value$, "D") + INSTR(value$, "E") 'only D or E can be present
  108.     IF Xpos% THEN
  109.         expo% = VAL(MID$(value$, Xpos% + 1))
  110.         IF VAL(value$) < 0 THEN
  111.             sign$ = "-": valu$ = MID$(value$, 2, Xpos% - 2)
  112.         ELSE valu$ = MID$(value$, 1, Xpos% - 1)
  113.         END IF
  114.         dot% = INSTR(valu$, "."): L% = LEN(valu$)
  115.         IF expo% > 0 THEN add$ = STRING$(expo% - (L% - dot%), "0")
  116.         IF expo% < 0 THEN min$ = STRING$(ABS(expo%) - (dot% - 1), "0"): DP$ = "."
  117.         FOR n = 1 TO L%
  118.             IF MID$(valu$, n, 1) <> "." THEN num$ = num$ + MID$(valu$, n, 1)
  119.         NEXT
  120.     ELSE DblToStr$ = value$: EXIT FUNCTION
  121.     END IF
  122.     DblToStr$ = _TRIM$(sign$ + DP$ + min$ + num$ + add$)
  123. END FUNCTION ' DblToStr$
  124.  
  125. ' /////////////////////////////////////////////////////////////////////////////
  126. ' Scientific notation - QB64 Wiki
  127. ' https://www.qb64.org/wiki/Scientific_notation
  128.  
  129. ' Example: A string function that displays extremely small or large exponential decimal values.
  130.  
  131. FUNCTION SngToStr$ (n!)
  132.     value$ = UCASE$(LTRIM$(STR$(n!)))
  133.     Xpos% = INSTR(value$, "D") + INSTR(value$, "E") 'only D or E can be present
  134.     IF Xpos% THEN
  135.         expo% = VAL(MID$(value$, Xpos% + 1))
  136.         IF VAL(value$) < 0 THEN
  137.             sign$ = "-": valu$ = MID$(value$, 2, Xpos% - 2)
  138.         ELSE valu$ = MID$(value$, 1, Xpos% - 1)
  139.         END IF
  140.         dot% = INSTR(valu$, "."): L% = LEN(valu$)
  141.         IF expo% > 0 THEN add$ = STRING$(expo% - (L% - dot%), "0")
  142.         IF expo% < 0 THEN min$ = STRING$(ABS(expo%) - (dot% - 1), "0"): DP$ = "."
  143.         FOR n = 1 TO L%
  144.             IF MID$(valu$, n, 1) <> "." THEN num$ = num$ + MID$(valu$, n, 1)
  145.         NEXT
  146.     ELSE SngToStr$ = value$: EXIT FUNCTION
  147.     END IF
  148.     SngToStr$ = _TRIM$(sign$ + DP$ + min$ + num$ + add$)
  149. END FUNCTION ' SngToStr$
  150.  
  151. ' /////////////////////////////////////////////////////////////////////////////
  152. ' By sMcNeill from https://www.qb64.org/forum/index.php?topic=896.0
  153.  
  154. FUNCTION IsNum% (text$)
  155.     DIM a$
  156.     DIM b$
  157.     a$ = _TRIM$(text$)
  158.     b$ = _TRIM$(STR$(VAL(text$)))
  159.     IF a$ = b$ THEN
  160.         IsNum% = TRUE
  161.     ELSE
  162.         IsNum% = FALSE
  163.     END IF
  164. END FUNCTION ' IsNum%
  165.  
  166. ' /////////////////////////////////////////////////////////////////////////////
  167.  
  168. FUNCTION RightPadString$ (myString$, toWidth%, padChar$)
  169.     RightPadString$ = LEFT$(myString$ + STRING$(toWidth%, padChar$), toWidth%)
  170. END FUNCTION ' RightPadString$
  171.  
  172. ' /////////////////////////////////////////////////////////////////////////////
  173.  
  174. FUNCTION cstr$ (myValue)
  175.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  176.     cstr$ = _TRIM$(STR$(myValue))
  177. END FUNCTION ' cstr$
  178.  

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: Rounding up to n decimal places?
« Reply #8 on: February 04, 2021, 06:51:19 pm »
Sometimes, you guys make things entirely too  complicated.
...
There ya go!  Three functions to either round naturally (0 - 0.4999999999999999999999 rounds down, 0.5 - 0.99999999999999999 rounds up), always round down, or always round up, to whatever number of digits you desire.

Wow, that's nice and simple, thanks!
One question: your functions receive and return type FLOAT.
What would the best way to handle a case where you want to pass in a single or double precision?
Would you have to convert the value to float, pass it in, then convert it back, or can the values be passed/returned as is?
Or would it be better to make copies of each of those functions for single and double precision?
Thanks again...

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Rounding up to n decimal places?
« Reply #9 on: February 04, 2021, 07:48:46 pm »
I haven't used _CEIL before, but doesn't that have a limit of 15 decimal places?

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

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Rounding up to n decimal places?
« Reply #10 on: February 04, 2021, 10:13:58 pm »
Wow, that's nice and simple, thanks!
One question: your functions receive and return type FLOAT.
What would the best way to handle a case where you want to pass in a single or double precision?
Would you have to convert the value to float, pass it in, then convert it back, or can the values be passed/returned as is?
Or would it be better to make copies of each of those functions for single and double precision?
Thanks again...

SINGLE, DOUBLE, and _FLOAT are all floating-point precision variable types.  The only difference in them is how much precision and how large a value they can hold.

If they were used for transportation, you could think of them as a compact car, a luxury suv, and a bus.  Now, ANY of those will let one person drive them to go to and from work, but the cost in resources (gas, in this case) for using them is going to be a little different. 

On the other hand, one person can ride a bus, but 32 people could never pack in a compact car!

So, if you think of your variable types like this, you can see why I chose to use _FLOAT.  A FLOAT will work just fine with SINGLE, or DOUBLE values, and the increase in memory usage will only be 28-bytes at most, and even then, those are temporary bites used, as they’re freed the moment you exit the function and get the return value.

Now, you COULD write it as a function that uses SINGLE variables, just to only use 4-bytes of memory, instead of the 32 that a float uses), but you’d always be stuck with the limits of a SINGLE’s precision.

Since the resource usage is temporary, and a trivial amount in this case (in relation to a programs overall memory allowable), I just chose to make the function a bus so it can always carry the maximum amount of passengers, and then I’ll never need to worry about swapping out to a larger vehicle.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: Rounding up to n decimal places?
« Reply #11 on: February 04, 2021, 10:58:08 pm »
SINGLE, DOUBLE, and _FLOAT are all floating-point precision variable types.  The only difference in them is how much precision and how large a value they can hold.
...
Since the resource usage is temporary, and a trivial amount in this case (in relation to a programs overall memory allowable), I just chose to make the function a bus so it can always carry the maximum amount of passengers, and then I’ll never need to worry about swapping out to a larger vehicle.

Sounds good to me. I liked your analogy of the compact car & bus. Maybe make the luxury SUV a pimpmobile!

Thanks again, and to everyone else who helped.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Rounding up to n decimal places?
« Reply #12 on: February 04, 2021, 11:15:13 pm »
I haven't used _CEIL before, but doesn't that have a limit of 15 decimal places?

Pete

INT always rounds down.  _CEIL always rounds up.  The limit is going to be based on your variable type.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Rounding up to n decimal places?
« Reply #13 on: February 05, 2021, 03:56:40 pm »
It's good to have, especially with QB64's INTEGER 64 variable type. Still, I just stick with strings when it comes to math. That's only limited by system memory.

Nice set of non-string functions, though!

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: Rounding up to n decimal places?
« Reply #14 on: February 05, 2021, 10:21:36 pm »
@Pete how many lines of code for your String math tools?

Mine ran about 300 not counting comments and demo's and helper subs.
https://www.qb64.org/forum/index.php?topic=2921.msg121886#msg121886

So is yours bigger than mine?