_Round () issue
#11
Isn't INT the equivalent of _FLOOR? Or is there a difference?

INT(-2.5) = -3, same as floor, unless it got broke somewhere.
Reply
#12
They're similar but _FLOOR should return a floating point number. Also for negative numbers the results are different. Take -99.5 for example. INT would return -99 whereas a _FLOOR function would return -100.0. At least that is my understanding. Hint - I haven't tried this out, just did a quick read.

TR
Reply
#13
No, honestly, they're *exactly* the same thing. Let me share some code for you.

First, the BAS code:

Code: (Select All)
A = Int(-99.5)

And then, if you look in internal/temp, you can see where this code is translated in c-code:

Code: (Select All)
*__SINGLE_A=floor( -99.5E+0 );

If you notice, INT translates directly into floor.  INT is the BASIC equivalent of floor.  It translates one-on-one to the other, and that's why we don't have a _FLOOR command -- BASIC already has INT.  Smile
Reply
#14
(05-13-2022, 10:49 AM)SMcNeill Wrote:
(05-13-2022, 01:08 AM)bplus Wrote:
(05-13-2022, 12:45 AM)dcromley Wrote: > bplus: "Luke explained it as bankers rounding, so that not every 5 is rounded up but every other 5 is."
 
  Yes, it is (now) clear that _ROUND rounds n.5 up if n is odd and down if n is even.
  Int(n.5) always rounds n.5 up.  SMcNeill's Round##(n.5,0) also always rounds up.

> aural: "Round() function always round to lower value"

  Wha--?

I'm sure just a mis-word but INT() always rounds down for positives anyway. 

BTW that's another crazy issue to worry about, rounding with negatives. I'm not sure you always want to add .5 in SMcNeill's Round##()

If not,then add * SGN(num) after that 0.5.  Tweak the behavior to whatever suits your personal needs/desires.

I tried that last night it was a mess!

Today I try removing neg sign, doing the calc and then putting the sign back in, interesting it fails or does bankers rounding! Not what I expected.
Code: (Select All)
Print "N", "Round", "Round Sgn", "Round Neg"
For n## = -1 To 1.00000001 Step .01
    Print n##, RoundOrig(n##, 1), RoundSgn(n##, 1), RoundNeg(n##, 1)
    i = i + 1
    If i Mod 20 = 0 Then Print "zzz... ": Sleep: Cls: Print "N", "Round", "Round Sgn", "Round Neg"
Next

Function RoundOrig## (num As _Float, toDecPlace As _Unsigned _Byte)
    RoundOrig## = Int(num * 10 ^ toDecPlace + .5) / 10 ^ toDecPlace
End Function

Function RoundSgn## (num As _Float, toDecPlace As _Unsigned _Byte)
    RoundSgn## = Int(num * 10 ^ toDecPlace + .5 * Sgn(num)) / 10 ^ toDecPlace
End Function

Function RoundNeg## (num As _Float, toDecPlace As _Unsigned _Byte)
    If num < 0 Then cnum = -1 * num: nFlag = -1 Else cnum = num: nFlag = 1
    RoundNeg## = nFlag * Int(cnum * 10 ^ toDecPlace + .5) / 10 ^ toDecPlace
End Function
b = b + ...
Reply
#15
What are you expecting? Maybe try FIX instead of INT. I'm not certain what results you're shooting for.
Reply
#16
Expected RoundNeg##(n, 1) to round negs like pos and then add a - sign to the calc.
b = b + ...
Reply
#17
(05-13-2022, 06:03 PM)bplus Wrote: Expected RoundNeg##(n, 1) to round negs like pos and then add a - sign to the calc.

Like this?

Code: (Select All)
Screen _NewImage(1024, 720, 32)

For i = 10.5 To -10.5 Step -.25
    If i = Int(i) Then Print
    Print i, Round(i, 0),

Next

Function Round## (num As _Float, toDecPlace As _Unsigned _Byte)
    Round = Fix(num * 10 ^ toDecPlace + .5 * Sgn(num)) / 10 ^ toDecPlace
End Function

If that's not what you're looking for, you'll need to spell it out with some numbers and what you expect to see them become.

+0.75 = +1
+0.5 = +1
+0.25 = 0
-0.25 = 0 
-0.5 = -1
-0.75 = -1

Or this formula as well, if you prefer:
Code: (Select All)
Function Round## (num As _Float, toDecPlace As _Unsigned _Byte)
    Round = Sgn(num) * Int(Abs(num) * 10 ^ toDecPlace + .5) / 10 ^ toDecPlace
End Function
Reply
#18
I  thought Int() was working differently on Wednesday than on Friday, but my thread-starting program was incorrect. ! I deleted that.  Gad!
I think this is correct (as I thought on Wednesday) and interesting: FWIW, this clearly shows the up and downs: (trust me):

Code: (Select All)
_Title "SCREEN256"
Option _Explicit
DefSng A-Z: DefLng I-N: DefStr S
Screen _NewImage(1024, 768, 256)
Color 0, 15
Cls

Dim Shared f
Dim n, k0, k1, k2, k3, k4
Print "  "; Chr$(34); "toLng"; Chr$(34); " is the conversion from a single to a long"
Print
Print "  f"; Tab(8); "  toLng"; Tab(18); "  Int(f)"; Tab(28); "  Fix(f)"; Tab(38); "_Round(f)"; Tab(48); "Round##(f,0)"
Print
For n = 19 To -20 Step -1
  f = n + .5
  k0 = f
  k1 = Int(f)
  k2 = Fix(f)
  k3 = _Round(f)
  k4 = Round##(f, 0)
  Print f; Tab(10); s(k0); Tab(20); s(k1); Tab(30); s(k2); Tab(40); s(k3); Tab(50); s(k4)
Next n

Function Round## (num As _Float, toDecPlace As _Unsigned _Byte) ' SMcNeill
  Round = Int(num * 10 ^ toDecPlace + .5) / 10 ^ toDecPlace
End Function

Function s (n) ' aligns n, adds up '^' or down 'v'
  Dim ss
  ss = Str$(n): If Len(ss) = 2 Then ss = " " + ss
  If n < f Then ss = ss + " v" Else ss = ss + " ^"
  s = ss
End Function

I never even considered the FIX function.
From the Wiki:
  The INT function rounds a numeric value down to the next whole number.
  The FIX function rounds a numerical value to the next whole number closest to zero.
  The _ROUND function rounds to the closest even .. numerical value.

And I'm quite sure (?) that Javascript says FLOOR() = INT()
Reply




Users browsing this thread: 10 Guest(s)