Yesterday, 10:39 AM
So these aren't new commands like most of the Extended KotD are, but these are some old commands that I *thought* I understood, only to realize I was 99% clueless about their behavior.
First, let me simply share links to their respect Wiki pages. Note that currently I find these pages inadequate, (which is one reason why I feel a new KOTD entry should be used to highlight everyone to the quirks associated with them), and since I have wiki editing mojo, these pages will probably change somewhat soon(tm). (I just want to give folks time to read this, see if I missed something, and if so, then I'll add in other's suggestions on these pages as well.)
WIKI LINKS:
https://qb64phoenix.com/qb64wiki/index.php/CINT
https://qb64phoenix.com/qb64wiki/index.php/CLNG
https://qb64phoenix.com/qb64wiki/index.php/%5C (This is the page on INTEGER DIVISION.. the \ operator)
Now, with the links out of the way, let me go over what the existing pages on CINT and CLNG tell us. Both say:
Sounds simple enough. Right? Less than 0.5 and we round down. More than 0.5 and we round up.
So here's my question for everyone -- What happens at EXACTLY 0.5? This tidbit of information isn't really listed anywhere, and if you go back and scour the web for old QB45 documents and help files, I doubt you'll find it either. I certainly didn't' anywhere that I looked on the net or all the resources I could find.
If your impressions are like mind, you would think, "rounds up or down to the nearest integer/long value", and you'd do rounding like always -- 0.5 and above rounds up.
And, you'd be *WRONG*!! (Just like me!)
CINT and CLNG work like this:
Values less than 0.5 are rounded down.
Values greater than 0.5 are rounded up.
Values exactly equal to 0.5 are rounded.... to the nearest even integer.
Now, study that last line there a few times and blink at it until it starts to sink in. Honestly, it took a while to make sense to me. Here's a little code snippet to run to see what I'm talking about yourself:
In this case, we see this:
1.5 rounds up to 2. 2 is the closest even integer.
2.5 rounds down to 2. 2 is the closest even integer.
3.5 rounds up.
4.5 rounds down.
5.5 rounds uo.
6.5 rounds down.
It's not a consistent 0.5 rounds up, or 0.5 rounds down. It's always 0.5 rounds to the nearest even integer.
That's an odd style result and needs to be documented and folks aware of it, if they're ever going to make any real use out of it without running into errors.
Less than 0.5 and it always rounds down.
More than 0.5 and it always rounds up.
At exactly 0.5, it rounds up or down, but always rounds to the nearest even integer.
Folks definitely need to be aware of this little quirk in CINT and CLNG.
And now that we have a basic understanding of these rounding tools, let's take a moment and talk about \ (INTEGER DIVISION).
The details here explain to us that:
Except that's not what we really see here.
With the little code above, we know that 5 / 3 would be 1.6666. The closest even integer to that value would be 2.
The result, however, is 1.
There's no rounding to the closest EVEN integer or long. Not even close, anywhere or anyway that I can tell. I've tested the heck out of this and here's what I've basically came up with on what's actually happening here:
x \ y <--- Let's say this is our basic integer division formula.
INT(CINT(x) / CINT(y)) <--- this is how it's actually processed and gets the final results for us.
Does that sound a little complicated? Try this little snippet and feel free to throw any other values you like at it to make certain the values match:
5 \ 3 .... this would yield 1.6666if we just divided 5 / 3, which we take the INT value of and make 1. That's the result we see.
5.5 \ 3 .... that 5.5 would CINT up to 6. 6 / 3 = 2. That's an integer already, so that's our result.
5 \ 2 ... this would yield 2.5 if we just divided it. We take the INT value of that and make 2.
5.5 \ 2.5 .... that 5,5 CINTs to become 6. The 2.5 CINTs to become 2. 6 /2 = 3, and that's our answer.
So.. what that comment in the wiki is referring to... I honestly don't know.
INTEGER DIVISION simply returns the INT value of division, and if we pass it non-integers to work with, it converts them via CINT or CLNG before processing them.
So.... Everyone follow along with all that? There's a lot of little nuance going on in the syntax and behavior here that folks should be aware of.
In conclusion:
CINT and CLNG round down if below 0.5, round up if above 0.5, and round to the nearest even integer if exactly 0.5.
When doing integer division (the \ math symbol), what we're actually doing is INT(CINT(x) / CINT(y)).
I'm not certain if other folks understood all these little quirks and what these commands are actually doing behind the scenes for us -- apparently, I didn't have a clue personally, and that's after programming in QBASIC for over 30 years!! None of the documentation I found explains these little distinctions, but as far as I can tell, we perfectly mimic the old QB45 behavior. This isn't a bug or a glitch... It's nothing new. It's the way it's always been, apparently.
It's just that NOW I can understand what it's doing, while in the past I only *thought* I knew -- and I was wrong over it all. LOL!!
Try it all out. Kick it around. See if you understand what I'm talking about here. If you guys find someplace that I'm wrong or something that doesn't fit this logic, then kindly post about it, correct me, and let's all get to understanding these commands better.
If everyone agrees with these conclusions, and doesn't find any flaw anywhere in what I'm telling you guys, I'll go in and update the wiki to reflect this additional information in about a week or so. (I want to give people time to respond first before making changes.)
Any and all comments, feedback, and cookies are welcome after banging my head on the desk for the past few days sorting into this mess.
First, let me simply share links to their respect Wiki pages. Note that currently I find these pages inadequate, (which is one reason why I feel a new KOTD entry should be used to highlight everyone to the quirks associated with them), and since I have wiki editing mojo, these pages will probably change somewhat soon(tm). (I just want to give folks time to read this, see if I missed something, and if so, then I'll add in other's suggestions on these pages as well.)
WIKI LINKS:
https://qb64phoenix.com/qb64wiki/index.php/CINT
https://qb64phoenix.com/qb64wiki/index.php/CLNG
https://qb64phoenix.com/qb64wiki/index.php/%5C (This is the page on INTEGER DIVISION.. the \ operator)
Now, with the links out of the way, let me go over what the existing pages on CINT and CLNG tell us. Both say:
Quote:The ... function rounds decimal point numbers up or down to the nearest INTEGER/LONG value.
Values greater than .5 are rounded up. Values lower than .5 are rounded down.
Sounds simple enough. Right? Less than 0.5 and we round down. More than 0.5 and we round up.
So here's my question for everyone -- What happens at EXACTLY 0.5? This tidbit of information isn't really listed anywhere, and if you go back and scour the web for old QB45 documents and help files, I doubt you'll find it either. I certainly didn't' anywhere that I looked on the net or all the resources I could find.
If your impressions are like mind, you would think, "rounds up or down to the nearest integer/long value", and you'd do rounding like always -- 0.5 and above rounds up.
And, you'd be *WRONG*!! (Just like me!)
CINT and CLNG work like this:
Values less than 0.5 are rounded down.
Values greater than 0.5 are rounded up.
Values exactly equal to 0.5 are rounded.... to the nearest even integer.
Now, study that last line there a few times and blink at it until it starts to sink in. Honestly, it took a while to make sense to me. Here's a little code snippet to run to see what I'm talking about yourself:
Code: (Select All)
For i = 1 To 10
x = i + .5
Print x, CInt(x)
Next
In this case, we see this:
1.5 rounds up to 2. 2 is the closest even integer.
2.5 rounds down to 2. 2 is the closest even integer.
3.5 rounds up.
4.5 rounds down.
5.5 rounds uo.
6.5 rounds down.
It's not a consistent 0.5 rounds up, or 0.5 rounds down. It's always 0.5 rounds to the nearest even integer.
That's an odd style result and needs to be documented and folks aware of it, if they're ever going to make any real use out of it without running into errors.
Less than 0.5 and it always rounds down.
More than 0.5 and it always rounds up.
At exactly 0.5, it rounds up or down, but always rounds to the nearest even integer.
Folks definitely need to be aware of this little quirk in CINT and CLNG.
And now that we have a basic understanding of these rounding tools, let's take a moment and talk about \ (INTEGER DIVISION).
The details here explain to us that:
Quote:Rounding is done to the closest EVEN integer or long integer value.
Except that's not what we really see here.
Code: (Select All)
Print 5 \ 3
With the little code above, we know that 5 / 3 would be 1.6666. The closest even integer to that value would be 2.
The result, however, is 1.
There's no rounding to the closest EVEN integer or long. Not even close, anywhere or anyway that I can tell. I've tested the heck out of this and here's what I've basically came up with on what's actually happening here:
x \ y <--- Let's say this is our basic integer division formula.
INT(CINT(x) / CINT(y)) <--- this is how it's actually processed and gets the final results for us.
Does that sound a little complicated? Try this little snippet and feel free to throw any other values you like at it to make certain the values match:
Code: (Select All)
Print 5 \ 3, Int_Div(5, 3)
Print 5.5 \ 3, Int_Div(5.5, 3)
Print 5 \ 2, Int_Div(5, 2)
Print 5.5 \ 2.5, Int_Div(5.5, 2.5)
Function Int_Div (x, y)
Int_Div = Int(CInt(x) / CInt(y))
End Function
5 \ 3 .... this would yield 1.6666if we just divided 5 / 3, which we take the INT value of and make 1. That's the result we see.
5.5 \ 3 .... that 5.5 would CINT up to 6. 6 / 3 = 2. That's an integer already, so that's our result.
5 \ 2 ... this would yield 2.5 if we just divided it. We take the INT value of that and make 2.
5.5 \ 2.5 .... that 5,5 CINTs to become 6. The 2.5 CINTs to become 2. 6 /2 = 3, and that's our answer.
So.. what that comment in the wiki is referring to... I honestly don't know.
INTEGER DIVISION simply returns the INT value of division, and if we pass it non-integers to work with, it converts them via CINT or CLNG before processing them.
So.... Everyone follow along with all that? There's a lot of little nuance going on in the syntax and behavior here that folks should be aware of.
In conclusion:
CINT and CLNG round down if below 0.5, round up if above 0.5, and round to the nearest even integer if exactly 0.5.
When doing integer division (the \ math symbol), what we're actually doing is INT(CINT(x) / CINT(y)).
I'm not certain if other folks understood all these little quirks and what these commands are actually doing behind the scenes for us -- apparently, I didn't have a clue personally, and that's after programming in QBASIC for over 30 years!! None of the documentation I found explains these little distinctions, but as far as I can tell, we perfectly mimic the old QB45 behavior. This isn't a bug or a glitch... It's nothing new. It's the way it's always been, apparently.
It's just that NOW I can understand what it's doing, while in the past I only *thought* I knew -- and I was wrong over it all. LOL!!
Try it all out. Kick it around. See if you understand what I'm talking about here. If you guys find someplace that I'm wrong or something that doesn't fit this logic, then kindly post about it, correct me, and let's all get to understanding these commands better.
If everyone agrees with these conclusions, and doesn't find any flaw anywhere in what I'm telling you guys, I'll go in and update the wiki to reflect this additional information in about a week or so. (I want to give people time to respond first before making changes.)
Any and all comments, feedback, and cookies are welcome after banging my head on the desk for the past few days sorting into this mess.
