Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - SMcNeill

Pages: 1 2 [3] 4 5 ... 265
31
Programs / Re: B+'s Matrix Rain With World Map Backdrop
« on: April 05, 2022, 03:16:25 pm »
Swapped everything over to hardware images, and suprisingly, it makes very little difference compared to what I have above.  Maybe a 10-20% increase in this case, and I wouldn't swear to that.

Code: QB64: [Select]
  1. _Title "Matrix Rain 4 mod by SierraKen mod b+" 'B+ started 2019-03-16
  2. ' Ken added great background and changed rain color
  3. ' 2022-04-05 b+ adjusted screen for x width 1024 for speedier graphics
  4. ' from Matrix Rain 2019-03-14
  5. ' or QB64 Purple Rain!
  6.  
  7. '>>> Save this file as: Matrix Rain 4 mod by SierraKen.bas, so the program can load the strings from it.  <<<
  8.  
  9. '2019-03-15 This will attempt to spin the drops as they fall
  10. '2019-03-16  Don't need no damn Character Set.DAT file!!!
  11. '2019-03-16 Ijust want to see the vertical code strings dangle and twist.
  12.  
  13. '2019-03-19 Matrix Rain 4
  14. ' + added randWeight to weight the random sizes chosen so many more on small side than large
  15. ' + draw letters on a transparent background so the background of the letter does not cover
  16. '   the drops behind it.
  17.  
  18. 'Mod by SierraKen - Added World Map as the backdrop. - April 2, 2022.
  19.  
  20. Const xmax = 1024
  21. Const ymax = 450
  22. Const nDrops = 500
  23. Type dropType
  24.     x As Single
  25.     sz As Single
  26.     curY As Integer
  27.     dxs As Single 'direction and change of spin some small fraction of 1, +-1/3, +-1/4, +-1/5...
  28.  
  29. 'SierraKen's World Map code with the array, GET, and DEST ---------------------------------------------
  30. Dim map As Long
  31. tmap& = _LoadImage("world_map2.jpg", 32)
  32. map& = _CopyImage(tmap&, 33)
  33.  
  34. WorkScreen = _NewImage(xmax, ymax, 32)
  35. Screen WorkScreen
  36. _ScreenMove 80, 0 'for snap shot
  37. '_FullScreen '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< optional full screen but out of proportion with map
  38.  
  39. ReDim Shared fileStrings$(1000) 'container for these program lines that will be dangling
  40. Open "Matrix Rain 4 mod by SierraKen.bas" For Input As #1
  41.     Line Input #1, fs$
  42.     If Len(LTrim$(fs$)) <> 0 Then 'less empty spaces
  43.         fileStrings$(i) = LTrim$(fs$)
  44.         i = i + 1
  45.     End If
  46. ReDim _Preserve fileStrings$(i - 1)
  47. ' check loading
  48. 'FOR i = 0 TO UBOUND(fileStrings$)
  49. '    PRINT i, fileStrings$(i)
  50. 'NEXT
  51. 'END
  52.  
  53. 'setup drops
  54. Dim Shared drop(nDrops) As dropType
  55. Dim Shared s$(nDrops)
  56.  
  57. For i = 0 To nDrops
  58.     newDrop i, 1
  59. While _KeyDown(27) = 0
  60.     'Cls , 0
  61.     'SierraKen's PUT statement ----------------------------
  62.     _PutImage , map&
  63.     '------------------------------------------------------
  64.  
  65.     For i = 0 To nDrops
  66.         drawDrop (i)
  67.         drop(i).curY = drop(i).curY + 1
  68.         If drop(i).curY > Len(s$(i)) Then newDrop i, 0
  69.     Next
  70.     _Display
  71.     fps = fps + 1
  72.     If Timer > FPStimer Then _Title "FPS:" + Str$(fps): fps = 0: FPStimer = Timer + 1
  73.     '_Limit 25
  74.  
  75. Sub newDrop (i, start)
  76.     drop(i).x = Rnd * xmax 'set location
  77.     drop(i).sz = randWeight(.3, 5, 3) 'set size  weighted on small sizes
  78.     'length of text string can fit on screen
  79.     charLength = ymax \ (drop(i).sz * 16) + 1 'from size determine how many chars fit on screen
  80.     randLine = Int(Rnd * UBound(fileStrings$)) 'pick a random program line
  81.     s$(i) = Mid$(fileStrings$(randLine), 1, charLength) 'here is text string to dangle
  82.     While Len(s$(i)) < charLength
  83.         If randLine + 1 > UBound(fileStrings$) Then randLine = 0 Else randLine = randLine + 1
  84.         s$(i) = Mid$(s$(i) + " : " + fileStrings$(randLine), 1, charLength)
  85.     Wend
  86.     If start <> 0 Then drop(i).curY = Int(Rnd * (charLength)) + 1 Else drop(i).curY = 1 'flat and readable at curY
  87.     drop(i).dxs = 1 / (Int(Rnd * 7) + 3) 'change of spin rate +-1/3, +-1/4, ... +-1/9
  88.     If Rnd < .5 Then drop(i).dxs = -drop(i).dxs
  89.  
  90. Sub drawDrop (i)
  91.     For j = 1 To drop(i).curY
  92.         d = drop(i).curY - j
  93.         rot = 1: dir = -1
  94.         For k = 0 To d
  95.             rot = rot + drop(i).dxs * dir
  96.             If rot > 1 Then
  97.                 dir = -1 * dir: rot = 1 + drop(i).dxs * dir
  98.             ElseIf rot < -1 Then
  99.                 dir = dir * -1: rot = -1 + drop(i).dxs * dir
  100.             End If
  101.         Next
  102.         drwChar Asc(s$(i), j), d, drop(i).x + 4 * drop(i).sz, drop(i).sz * 16 * (j - 1) + 8 * drop(i).sz, rot * drop(i).sz, drop(i).sz, 0
  103.     Next
  104.  
  105. Sub drwChar (char, c As _Unsigned Long, midX, midY, xScale, yScale, Rotation) 'what ever the present color is set at
  106.     Static I(18, 255) As Long
  107.     If I(0, 0) = 0 Then
  108.         For d = 0 To 18 '18 rows of letters for all the colors possible in the program
  109.             If d = 0 Then
  110.                 ColorSet& = _RGBA32(0, 255, 0, 225)
  111.             ElseIf d = 1 Then
  112.                 ColorSet& = _RGBA32(50, 255, 0, 205)
  113.             ElseIf d = 2 Then
  114.                 ColorSet& = _RGBA32(25, 255, 0, 180)
  115.             ElseIf d >= 3 And d <= 18 Then
  116.                 ColorSet& = _RGBA32(0, 255, 0, 190 - d * 5)
  117.             Else 'beyond this value, the 190 - d * 5 becomes a negative value?
  118.                 'For values beyond this, I'm just going to exit the sub and whistle innocently, uncertain what they're supposed to be....  *whistle*
  119.             End If
  120.             For ch = 0 To 255 '256 columns for the letters.
  121.                 temp = _NewImage(8, 16, 32)
  122.                 _Dest temp
  123.                 Color ColorSet&, 0
  124.                 _PrintString (0, 0), Chr$(ch)
  125.                 I(d, ch) = _CopyImage(temp, 33)
  126.             Next
  127.         Next
  128.         _Dest 0
  129.     End If
  130.     If c > 18 Then Exit Sub ' *whistle*  *whistele*
  131.     RotoZoom2 midX, midY, I(c, char), xScale, yScale, Rotation
  132.  
  133. Sub RotoZoom2 (X As Long, Y As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
  134.     Dim px(3) As Single: Dim py(3) As Single
  135.     W& = _Width(Image&): H& = _Height(Image&)
  136.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  137.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  138.     sinr! = Sin(-Rotation): cosr! = Cos(-Rotation)
  139.     For i& = 0 To 3
  140.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + Y
  141.         px(i&) = x2&: py(i&) = y2&
  142.     Next
  143.     _MapTriangle (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  144.     _MapTriangle (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  145.  
  146. Function randWeight (manyValue, fewValue, power)
  147.     randWeight = manyValue + Rnd ^ power * (fewValue - manyValue)
  148.  
  149.  
  150.  
  151.  

Best I can tend to max out with is about 140 FPS on my laptop.   

32
Programs / Re: B+'s Matrix Rain With World Map Backdrop
« on: April 05, 2022, 02:51:01 pm »
Trying it, I'm getting about twice the FPS on my machine:

Code: QB64: [Select]
  1. _Title "Matrix Rain 4 mod by SierraKen mod b+" 'B+ started 2019-03-16
  2. ' Ken added great background and changed rain color
  3. ' 2022-04-05 b+ adjusted screen for x width 1024 for speedier graphics
  4. ' from Matrix Rain 2019-03-14
  5. ' or QB64 Purple Rain!
  6.  
  7. '>>> Save this file as: Matrix Rain 4 mod by SierraKen.bas, so the program can load the strings from it.  <<<
  8.  
  9. '2019-03-15 This will attempt to spin the drops as they fall
  10. '2019-03-16  Don't need no damn Character Set.DAT file!!!
  11. '2019-03-16 Ijust want to see the vertical code strings dangle and twist.
  12.  
  13. '2019-03-19 Matrix Rain 4
  14. ' + added randWeight to weight the random sizes chosen so many more on small side than large
  15. ' + draw letters on a transparent background so the background of the letter does not cover
  16. '   the drops behind it.
  17.  
  18. 'Mod by SierraKen - Added World Map as the backdrop. - April 2, 2022.
  19.  
  20. Const xmax = 1024
  21. Const ymax = 450
  22. Const nDrops = 500
  23. Type dropType
  24.     x As Single
  25.     sz As Single
  26.     curY As Integer
  27.     dxs As Single 'direction and change of spin some small fraction of 1, +-1/3, +-1/4, +-1/5...
  28.  
  29. 'SierraKen's World Map code with the array, GET, and DEST ---------------------------------------------
  30. Dim map As Long
  31. tmap& = _LoadImage("world_map2.jpg", 32)
  32. map& = _CopyImage(tmap&, 33)
  33.  
  34. WorkScreen = _NewImage(xmax, ymax, 32)
  35. Screen WorkScreen
  36. _ScreenMove 80, 0 'for snap shot
  37. '_FullScreen '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< optional full screen but out of proportion with map
  38.  
  39. ReDim Shared fileStrings$(1000) 'container for these program lines that will be dangling
  40. Open "Matrix Rain 4 mod by SierraKen.bas" For Input As #1
  41.     Line Input #1, fs$
  42.     If Len(LTrim$(fs$)) <> 0 Then 'less empty spaces
  43.         fileStrings$(i) = LTrim$(fs$)
  44.         i = i + 1
  45.     End If
  46. ReDim _Preserve fileStrings$(i - 1)
  47. ' check loading
  48. 'FOR i = 0 TO UBOUND(fileStrings$)
  49. '    PRINT i, fileStrings$(i)
  50. 'NEXT
  51. 'END
  52.  
  53. 'setup drops
  54. Dim Shared drop(nDrops) As dropType
  55. Dim Shared s$(nDrops)
  56.  
  57. For i = 0 To nDrops
  58.     newDrop i, 1
  59. While _KeyDown(27) = 0
  60.     Cls , 0
  61.     'SierraKen's PUT statement ----------------------------
  62.     _PutImage , map&
  63.     '------------------------------------------------------
  64.  
  65.     For i = 0 To nDrops
  66.         drawDrop (i)
  67.         drop(i).curY = drop(i).curY + 1
  68.         If drop(i).curY > Len(s$(i)) Then newDrop i, 0
  69.     Next
  70.     _Display
  71.     fps = fps + 1
  72.     If Timer > FPStimer Then _Title "FPS:" + Str$(fps): fps = 0: FPStimer = Timer + 1
  73.     '_Limit 25
  74.  
  75. Sub newDrop (i, start)
  76.     drop(i).x = Rnd * xmax 'set location
  77.     drop(i).sz = randWeight(.3, 5, 3) 'set size  weighted on small sizes
  78.     'length of text string can fit on screen
  79.     charLength = ymax \ (drop(i).sz * 16) + 1 'from size determine how many chars fit on screen
  80.     randLine = Int(Rnd * UBound(fileStrings$)) 'pick a random program line
  81.     s$(i) = Mid$(fileStrings$(randLine), 1, charLength) 'here is text string to dangle
  82.     While Len(s$(i)) < charLength
  83.         If randLine + 1 > UBound(fileStrings$) Then randLine = 0 Else randLine = randLine + 1
  84.         s$(i) = Mid$(s$(i) + " : " + fileStrings$(randLine), 1, charLength)
  85.     Wend
  86.     If start <> 0 Then drop(i).curY = Int(Rnd * (charLength)) + 1 Else drop(i).curY = 1 'flat and readable at curY
  87.     drop(i).dxs = 1 / (Int(Rnd * 7) + 3) 'change of spin rate +-1/3, +-1/4, ... +-1/9
  88.     If Rnd < .5 Then drop(i).dxs = -drop(i).dxs
  89.  
  90. Sub drawDrop (i)
  91.     For j = 1 To drop(i).curY
  92.         d = drop(i).curY - j
  93.         rot = 1: dir = -1
  94.         For k = 0 To d
  95.             rot = rot + drop(i).dxs * dir
  96.             If rot > 1 Then
  97.                 dir = -1 * dir: rot = 1 + drop(i).dxs * dir
  98.             ElseIf rot < -1 Then
  99.                 dir = dir * -1: rot = -1 + drop(i).dxs * dir
  100.             End If
  101.         Next
  102.         drwChar Asc(s$(i), j), d, drop(i).x + 4 * drop(i).sz, drop(i).sz * 16 * (j - 1) + 8 * drop(i).sz, rot * drop(i).sz, drop(i).sz, 0
  103.     Next
  104.  
  105. Sub drwChar (char, c As _Unsigned Long, midX, midY, xScale, yScale, Rotation) 'what ever the present color is set at
  106.     Static I(18, 255) As Long
  107.     If I(0, 0) = 0 Then
  108.         For d = 0 To 18 '18 rows of letters for all the colors possible in the program
  109.             If d = 0 Then
  110.                 ColorSet& = _RGBA32(0, 255, 0, 225)
  111.             ElseIf d = 1 Then
  112.                 ColorSet& = _RGBA32(50, 255, 0, 205)
  113.             ElseIf d = 2 Then
  114.                 ColorSet& = _RGBA32(25, 255, 0, 180)
  115.             ElseIf d >= 3 And d <= 18 Then
  116.                 ColorSet& = _RGBA32(0, 255, 0, 190 - d * 5)
  117.             Else 'beyond this value, the 190 - d * 5 becomes a negative value?
  118.                 'For values beyond this, I'm just going to exit the sub and whistle innocently, uncertain what they're supposed to be....  *whistle*
  119.             End If
  120.             For ch = 0 To 255 '256 columns for the letters.
  121.                 I(d, ch) = _NewImage(8, 16, 32)
  122.                 _Dest I(d, ch)
  123.                 Color ColorSet&, 0
  124.                 _PrintString (0, 0), Chr$(ch)
  125.             Next
  126.         Next
  127.         _Dest 0
  128.     End If
  129.     If c > 18 Then Exit Sub ' *whistle*  *whistele*
  130.     RotoZoom2 midX, midY, I(c, char), xScale, yScale, Rotation
  131.  
  132. Sub RotoZoom2 (X As Long, Y As Long, Image As Long, xScale As Single, yScale As Single, Rotation As Single)
  133.     Dim px(3) As Single: Dim py(3) As Single
  134.     W& = _Width(Image&): H& = _Height(Image&)
  135.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  136.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  137.     sinr! = Sin(-Rotation): cosr! = Cos(-Rotation)
  138.     For i& = 0 To 3
  139.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * xScale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * yScale + Y
  140.         px(i&) = x2&: py(i&) = y2&
  141.     Next
  142.     _MapTriangle (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  143.     _MapTriangle (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  144.  
  145. Function randWeight (manyValue, fewValue, power)
  146.     randWeight = manyValue + Rnd ^ power * (fewValue - manyValue)
  147.  

You'll have to read my comments though...  *whistles innocently*.   Your math leaves me a little confuzzled at one point in the code, so ..  *whistles innocently*...

33
Programs / Re: B+'s Matrix Rain With World Map Backdrop
« on: April 05, 2022, 02:19:56 pm »
If you're wanting to speed it up, here's what I'd suggest:

Code: QB64: [Select]
  1. Sub drwChar (char$, c As _Unsigned Long, midX, midY, xScale, yScale, Rotation) 'what ever the present color is set at
  2.     I& = _NewImage(8, 16, 32)
  3.     _Dest I&
  4.     Color c, _RGBA32(0, 0, 0, 0)
  5.     _PrintString (0, 0), char$
  6.     _Dest 0
  7.     RotoZoom2 midX, midY, I&, xScale, yScale, Rotation
  8.     _FreeImage I&

This routine here is very unoptimized and inefficient.  You're drawing each letter every time you need it and then freeing the image that you drew it on over and over repeatedly.  I can see why you're going this route -- you've got multiple colors to deal with -- but here's my suggestion:

Make a single sprite array once for processing and keep it for the length of the program's running.

STATIC I(3,255) AS LONG
IF I(0,0) = 0 THEN
    FOR colors = 0 to 3 '4 rows of letters for the 4 colors possible in the program
        FOR characters = 0 to 255 '256 columns for the letters.
            I(colors, characters) = _newimage(8, 16, 32)
... stuff
END IF

Now, instead of passing a char$, you'd be passing the ASCII value of your character, and instead of passing c, you'd simply be passing d.  The whole IF d = 0 ELSEIF , ELSEIF, ELSEIF, ELSE block could be removed, and you'd get rid of the slow Mid$(s$(i), j, 1) and replace it with a simple ASC(s$(i),j).  There'd be no redrawing of each letter over and over, and no need to constantly allocate and free memory in the program. 

I haven't tried it, but from what I can tell looking over the code, I imagine that your bottleneck in performance is in the above routine, and I think this could fix it.  ;)


34
QB64 Discussion / Re: Fickle Increment variable
« on: April 05, 2022, 01:44:57 pm »
Why _KEYDOWN?  Why not use the _KEYHIT buffer instead?

35
QB64 Discussion / Re: big number
« on: April 05, 2022, 12:33:53 am »
thank you so much.  I'm working on a time calculator with precision to the second and trying to convert years to seconds. A LONG doesn't allow more than 10 years or so. Thanks again

Code: QB64: [Select]
  1.  
  2. FUNCTION TimeStamp## (d$, t##) 'date and timer
  3.     'Based on Unix Epoch time, which starts at year 1970.
  4.     DIM s AS _FLOAT
  5.  
  6.     l = INSTR(d$, "-")
  7.     l1 = INSTR(l + 1, d$, "-")
  8.     m = VAL(LEFT$(d$, l))
  9.     d = VAL(MID$(d$, l + 1))
  10.     y = VAL(MID$(d$, l1 + 1))
  11.     IF y < 1970 THEN 'calculate shit backwards
  12.         SELECT CASE m 'turn the day backwards for the month
  13.             CASE 1, 3, 5, 7, 8, 10, 12: d = 31 - d '31 days
  14.             CASE 2: d = 28 - d 'special 28 or 29.
  15.             CASE 4, 6, 9, 11: d = 30 - d '30 days
  16.         END SELECT
  17.         IF y MOD 4 = 0 AND m < 3 THEN 'check for normal leap year, and we're before it...
  18.             d = d + 1 'assume we had a leap year, subtract another day
  19.             IF y MOD 100 = 0 AND y MOD 400 <> 0 THEN d = d - 1 'not a leap year if year is divisible by 100 and not 400
  20.         END IF
  21.  
  22.         'then count the months that passed after the current month
  23.         FOR i = m + 1 TO 12
  24.             SELECT CASE i
  25.                 CASE 2: d = d + 28
  26.                 CASE 3, 5, 7, 8, 10, 12: d = d + 31
  27.                 CASE 4, 6, 9, 11: d = d + 30
  28.             END SELECT
  29.         NEXT
  30.  
  31.         'we should now have the entered year calculated.  Now lets add in for each year from this point to 1970
  32.         d = d + 365 * (1969 - y) '365 days per each standard year
  33.         FOR i = 1968 TO y + 1 STEP -4 'from 1968 onwards,backwards, skipping the current year (which we handled previously in the FOR loop)
  34.             d = d + 1 'subtract an extra day every leap year
  35.             IF (i MOD 100) = 0 AND (i MOD 400) <> 0 THEN d = d - 1 'but skipping every year divisible by 100, but not 400
  36.         NEXT
  37.         s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  38.         TimeStamp## = -(s## + 24 * 60 * 60 - t##)
  39.         EXIT FUNCTION
  40.     ELSE
  41.         y = y - 1970
  42.     END IF
  43.  
  44.     FOR i = 1 TO m 'for this year,
  45.         SELECT CASE i 'Add the number of days for each previous month passed
  46.             CASE 1: d = d 'January doestn't have any carry over days.
  47.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  48.             CASE 3 'Feb might be a leap year
  49.                 IF (y MOD 4) = 2 THEN 'if this year is divisible by 4 (starting in 1972)
  50.                     d = d + 29 'its a leap year
  51.                     IF (y MOD 100) = 30 AND (y MOD 400) <> 30 THEN 'unless..
  52.                         d = d - 1 'the year is divisible by 100, and not divisible by 400
  53.                     END IF
  54.                 ELSE 'year not divisible by 4, no worries
  55.                     d = d + 28
  56.                 END IF
  57.             CASE 5, 7, 10, 12: d = d + 30
  58.         END SELECT
  59.     NEXT
  60.     d = (d - 1) + 365 * y 'current month days passed + 365 days per each standard year
  61.     FOR i = 2 TO y - 1 STEP 4 'from 1972 onwards, skipping the current year (which we handled previously in the FOR loopp)
  62.         d = d + 1 'add an extra day every leap year
  63.         IF (i MOD 100) = 30 AND (i MOD 400) <> 30 THEN d = d - 1 'but skiping every year divisible by 100, but not 400
  64.     NEXT
  65.     s## = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  66.     TimeStamp## = (s## + t##)
  67.  

Pass it a date and timer and it calculates a timestamp for use.

36
QB64 Discussion / Re: Variable v's Fixed Value
« on: April 04, 2022, 11:42:10 am »
I've seen "Quasi-Constants" in use before.  In fact, QB64 itself has some.  If you look in the internal directory, you'll see our config.ini file.  It has a whole list of quasi-constants which we make use of.  For example, we have: TextColor=_RGB32(216, 216, 216).

TextColor is <almost> a CONST in the fact that even though it's used constantly inside our program, the value can really only be changed via one specific user action -- Menu, Options, IDE Colors.  At no point do we assign a value to it anywhere else inside the code, besides that one specific spot, even though we might read that value and use it in multiple modules.

Being able to call Color TextColor or Color BackgroundColor or Color QuoteColor is much easier to use and keep up with than trying to remember Color 4, 7, 11 for those 3 values (if that's even what they actually map to.  I'd have to look them up to be certain now, since we use the variable names internally and not the values themselves.)

They're used similar to CONST, with the exception that they *can* be changed -- but only in the proper condition and usage.  Does that make them "quasi-Const"?

37
QB64 Discussion / Re: Variable v's Fixed Value
« on: April 04, 2022, 10:38:38 am »
Because it is however a "variable" do you have some trick that you use to be sure "zoom" doesn't change in value?

Make it a CONST.

Const Zoom = 2

38
QB64 Discussion / Re: Question regarding interacting with Excel files
« on: April 04, 2022, 09:02:45 am »
Well the Excel as found in Office 2003 was XLS and you can't get Office 2003 anymore even as a download...

https://archive.org/details/MicrosoftOffice2003StandardEdition11.0.5510.02003English

It's the age of the internet.  Nothing ever really disappears anymore.

39
QB64 Discussion / Re: Question regarding interacting with Excel files
« on: April 04, 2022, 01:47:21 am »
Hi ya NcNeil
I have been away for awhile a much needed break from programming in general.

Excel went downhill after the .XLS format was obsoleted.
  Excel was my go to for number crunching because I could do graphs easily with maths

As far as I know, XLS never got obsoleted.  It just got upgraded to XLSX, which is a specially named ZIP folder which holds the XLM files inside it along with all your resource files like embedded fonts, sounds,  and graphics. 

When did XLS get obsoleted?  Did I miss something?  (As I said, I don't hardly ever use Excel or Power Point -- almost all my work is always in Word.)

40
Programs / Re: and another one for your toolbox...
« on: April 03, 2022, 03:47:55 am »
Here's a very short little tool for your toolbox:

Code: QB64: [Select]
  1. i = 2
  2.     Print i, Digits(i)
  3.     i = i * 2
  4. Loop Until Digits(i) > 7
  5.  
  6. Function Digits&& (value As Double)
  7.     Digits&& = Int(Log(Abs(value)) / Log(10.#)) + 1
  8.  

Function Digits tells you how many digits a number has, not counting any decimal places.  Can be much faster and simpler than something like Len(_Trim$(Str$(INT(number)))) + (Sgn(number) = -1) , which does the same thing (for integer values) by converting the number to a string first.

41
Hey Steve I was thinking - uh oh, get ready...

...and I know you're infinitely busy already, all thoughts and prayers going your way. That said, can I humbly encourage your QB64 Bible project to hit the issue of floating point math next? Even if it wasn't the next chapter you were going to write, we need something final on this question once and for all. It comes up way too often in the forums. The proper write-up should minimize out-of-house references, and be something written entirely by us, for us -  and you're the guy to do it Steve. The challenge is to write it out *so good* that it answers every question that ever came up about floating point math in qb64.exe, and also anticipates every future question that may arise. Do whatever you want to do, but make this section stand perfectly alone, and write it soon. No references to other chapters, just a stand alone gospel on QB64's float.

This might make the overall project feel less daunting. Do chapters by demand. Do float while it's fresh. Invest the 10,000 keystrokes and you'll save us all 100,000. Pretty Virginia Please.

The problem with floating point stuff is that *even I* -- as unbelievable as that sounds -- am still learning more about how it behaves and what its quirks are all the time.

Here's a quirk I just picked up on a little while ago that made me just close my QB64 window and give up on things for a while:

Code: QB64: [Select]
  1. i = -1.9
  2. x## = i
  3. Print i, x##

i is a single, and it's value isi -1.9.  x## is a float -- much more precision to work with than a trifling single, so the value should be the same easily.  Right??

  [ You are not allowed to view this attachment ]  

WRONG!!

By passing a SINGLE into a SUB/FUNCTION that looks for a _FLOAT, the value can change just because the variable type used to store that value changed!!

Who would've ever thunk that??  Especially since we're going from low precision floats to high precision floats.  I could almost understand if a float held a value that a single couldn't, but in this case, I'm just blown away by the value change.

Floating Point wierdness....

Can *anyone* ever really write a end-all testament to describe all the oddness that it can perform??

42
While... Wend or Do...Loop or GOTO whatever...  *WON'T* make any difference.

The problem is -- and say it with me when I repeat it once more guys -- IT'S IMPOSSIBLE TO PERFECTLY REPRESENT 1/10 IN BINARY FORMAT!!  It simply can't be done!

1/10 is a flawed representation in binary, just as it's impossible to perfect represent 1/3 in decimal.  All you can do is give the closest working estimation for the value -- which is basically a "close enough" figure for most applications.   

The initial value of 1/10 is flawed, by its very nature in binary.  Adding it up repeatedly, in ANY sort of situation -- loop or not -- simply increases the magnitude of that incremental flaw.

Charlie has a good, working solution: Convert to integer values and do away with the floating point inaccuracies completely.  Minimizing usage of floating point variables minimizes the loss of precision which is inherent in their very nature.

It's just the inherent nature of the math base at work.


43
I don't know if I can ever again trust a loop that involves incrementing by decimal values.

Maybe a knee-jerk reaction, but I find myself wondering, looking at any kind of loop like that, if there is unintentional short-changing of the loop (or an opposite "over-loop"?) by an iteration.

It's always a possibility.

FOR i = -1 TO 1 STEP 0.1

NEXT

In the above, even if we add a line that sets i to being exactly 0.9, we can't be certain that the increment won't make it's value 1.00000001 -- which is greater than 1 and will xit the loop one step early!

The only way to be certain we get that final loop is by adding a tolerance level into the code for floating point imperfections:

FOR i = -1 TO 1.01 STEP 0.1

NEXT

The end point is now great enough to absorb the error, but not large enough to allow an extra increment to pass.



I still say the absolute best solution, when possible, is to just avoid the floating point imperfections entirely.

FOR i = -10 TO 10 'use integers when possible
  iDec = i /10 'only convert to the floating point value when necessary
NEXT

It's why the banks track how many PENNIES are in your account, and not how many dollars.  The results are displayed as dollars, but all the calculations are in pennies.

44
Steve said it some time ago, I paraphrase: Separate the calculations with variables function from the displaying of the results function.

You just need a good format routine to adjust for garbage that enters into calculations with floats. Probably would include rounding to the precision of decimals you desire in the output (display) format.

For CharlieJV this seems to work:
Code: QB64: [Select]
  1. For i = -1 To 1 Step .1
  2.     Print i, format$("##.#", Str$(i))
  3.  
  4. Function format$ (template As String, Source As String)
  5.     Dim d, s, n, i, t$
  6.     d = _Dest: s = _Source
  7.     n = _NewImage(80, 80, 0)
  8.     _Dest n: _Source n
  9.     Print Using template; Val(Source)
  10.     For i = 1 To 79
  11.         t$ = t$ + Chr$(Screen(1, i))
  12.     Next
  13.     If Left$(t$, 1) = "%" Then t$ = Mid$(t$, 2)
  14.     format$ = _Trim$(t$)
  15.     _Dest d: _Source s
  16.     _FreeImage n
  17.  
  18.  
 [ You are not allowed to view this attachment ]  

Well shoot, seems to be stopping at .9 not 1, dang!

OK this fixes that!
Code: QB64: [Select]
  1. For i = -1 To 1.0001 Step .1
  2.     Print i, format$("##.#", Str$(i))
  3. Function format$ (template As String, Source As String)
  4.     Dim d, s, n, i, t$
  5.     d = _Dest: s = _Source
  6.     n = _NewImage(80, 80, 0)
  7.     _Dest n: _Source n
  8.     Print Using template; Val(Source)
  9.     For i = 1 To 79
  10.         t$ = t$ + Chr$(Screen(1, i))
  11.     Next
  12.     If Left$(t$, 1) = "%" Then t$ = Mid$(t$, 2)
  13.     format$ = _Trim$(t$)
  14.     _Dest d: _Source s
  15.     _FreeImage n
  16.  

The one issue with using format$ (or Print Using) to display your results is the simple fact that:

1) You're still going to be dealing with actually incorrect values.  If you have a line of code in that IF block that read something like IF i = 0.9 THEN...   you'd have a false result as I would be 0.90000002 and not 0.9.
2) Since i holds those incorrect rounding errors, the error is going to keep growing ever larger over time.  Notice in your screenshot where it's 0.80000001 -- a variance of 0.0000001, and then the next value is 0.90000002...  The glitch grows over time!

Round to the desired precision as you go and your problem goes away without accumulating and adding up over time to become a major issue for you.  ;)

45
Notice how the fix can also be applied for Doppler's problem as well: 
Code: QB64: [Select]
  1. _Title "Total it" ' from Doppler "defsng math going off the rails, creating a total from list of numbers in file"
  2. ' ref: https://qb64forum.alephc.xyz/index.php?topic=4753.msg141698#msg141698
  3. total = 0
  4. t = 0
  5.  
  6.     Read t$
  7.     If t$ = "EOD" Then Exit Do
  8.     t = Fix_Precision(Val(t$))
  9.     Print t
  10.     Print Str$(total) + " plus " + t$ + " equals ";
  11.     total = Fix_Precision(total + t)
  12.     Print total;
  13.     Print " press any to contiue..."
  14.     Sleep
  15. Data -750,21.71,13.67,22.92,91.25,119.63,10.84,18.46,40.44,171.73,3.08,92.39,57.20,22.79,-2.80,43.87,34.81,83.82,10.85,EOD
  16.  
  17.  
  18. Function Fix_Precision## (value##)
  19.     Fix_Precision = Int(value## * 100 + .5) / 100


Pages: 1 2 [3] 4 5 ... 265