changing operators // and //= to only do integer or floor division

Discuss the future of the AutoHotkey language
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

changing operators // and //= to only do integer or floor division

22 Sep 2018, 04:19

- Like <>, this pull request would likely prompt a lot of discussion:
Changing operators // and //= to only do integer division. by HelgeffegleH · Pull Request #116 · Lexikos/AutoHotkey_L · GitHub
https://github.com/Lexikos/AutoHotkey_L/pull/116
- Here's a summary of the current behaviour:

Code: Select all

q:: ;test // in AHK v1
MsgBox, % (3 // 2) ;1 ;integer division: round towards 0
MsgBox, % (3.0 // 2) ;1.000000 ;floor division: round down

MsgBox, % (-3 // 2) ;-1 ;integer division: round towards 0
MsgBox, % (-3.0 // 2) ;-2.000000 ;floor division: round down

MsgBox, % (3 // -2) ;-1 ;integer division: round towards 0
MsgBox, % (3.0 // -2) ;-2.000000 ;floor division: round down

MsgBox, % (-3 // -2) ;1 ;integer division: round towards 0
MsgBox, % (-3.0 // -2) ;1.000000 ;floor division: round down
return
- Link:
Variables and Expressions - Definition & Usage | AutoHotkey
https://autohotkey.com/docs/Variables.htm#MulDiv

- There's a logic to making // consistent for floats and integers. They handle positive results in the same way, but handle negative results differently (rounding them towards 0 (up), or down).
- I would consider how other programming languages do it. Python always rounds down, it uses floor division: e.g. -3 // 2 = -2 and -3.0 // 2 = -2.0. (C++ and Java use // for comments.)
- Which would break more scripts, the round towards 0 or the round down behaviour?
- (I'd be tempted to use the round down behaviour always, this would maintain the 'floor division' name and seems more useful. The round towards 0 behaviour doesn't seem useful to me, but maybe there are arguments for it.)
- (The pull request proposal would make // be 'integer division', which seems to me the wrong way to go.)
- Potentially, if people wanted, an IntDiv (or other name) function could be added.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
guest3456
Posts: 3134
Joined: 09 Oct 2013, 10:31

Re: changing operators // and //= to only do integer or floor division

22 Sep 2018, 08:18

Helgef already addressed your point in the PR:
floor divide is already possible with (more readable) floor(x/y)
you ignored mentioning this function in your post. you are basically suggesting that Floor() and // be exactly the same (round down), yes?

User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: changing operators // and //= to only do integer or floor division

22 Sep 2018, 09:34

- In AHK v2 you can do Floor(x/y) and Integer(x/y).
- So the question is, who gets to be //.
- I suggested // be Floor(x/y) to match Python 3.
- I haven't seen any language use // to mean Int(x/y).
- In the 5 most-used languages, // is either floor division or inline comment.
- Also, I suggested Integer() become Int().

- // is used for inline comments in many languages:
Comparison of programming languages (syntax) - Wikipedia
https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(syntax)#Comments
ActionScript, C (C99), C++, C#, D, F#, Go, Java, JavaScript, Kotlin, Object Pascal (Delphi), Objective-C, PHP, Rust, Scala, SASS, Swift, Xojo
Last edited by jeeswg on 11 Mar 2019, 17:22, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
tank
Posts: 2833
Joined: 28 Sep 2013, 22:15
Facebook: charlie.simmons.7334
Google: ttnnkkrr
GitHub: ttnnkkrr
Location: Irving TX
Contact:

Re: changing operators // and //= to only do integer or floor division

22 Sep 2018, 09:58

jeeswg wrote:(So first my posts are too long for you, now they're too short!?)
what precisely is your point here your entire post could be reduced to the word yes.
Many of your points are off-topic or rambling
We are troubled on every side‚ yet not distressed; we are perplexed‚
but not in despair; Persecuted‚ but not forsaken; cast down‚ but not destroyed;
https://www.facebook.com/ahkscript.org
If you have forum suggestions please submit a pull request
Check Out WebWriter
Thanks Tank :thumbup:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: changing operators // and //= to only do integer or floor division

22 Sep 2018, 10:23

- @tank: I'm anticipating follow-up questions, avoiding a prolonged back and forth. I'm just saving time.
- Btw not everyone will be fully clued up on all topics before reading.
- When I asked you to point to one post of mine that could be improved, it was already quite short with simple sentences, and yet you edited it to the point where you'd removed most of the useful information!?
- I've only had less than a handful of people complain about my more thorough posts, but these people tend to be a bit complacent in several respects, and I've noticed other trends, but I'd rather not go into it.
Last edited by jeeswg on 11 Mar 2019, 17:30, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
iseahound
Posts: 610
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: changing operators // and //= to only do integer or floor division

24 Sep 2018, 19:22

Hmm... this is really interesting.

In OCaml, there are different operators for floats and integers.
Image
Image

Typically the operators are overridden into:
Image

I'm against // because how would we do integer add, subtract, and multiply?
Finally, for most people // just means "discard the remainder".

Source: https://medium.com/arena-tech-blog/ocam ... a33bb39072
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: changing operators // and //= to only do integer or floor division

25 Sep 2018, 05:08

- Thanks iseahound, that is an interesting source. How common is OCaml?

- The PR mentioned that if you wanted to do floor division you could use Floor. Well likewise, if you wanted to do integer division you could use Integer.
- And so the question becomes: which is more standard, // for floor division or integer division, Python for example uses floor division.

Code: Select all

MsgBox(-3 / 2) ;-1.5
MsgBox(-3.0 / 2.0) ;-1.5

MsgBox(-3 // 2) ;-1 ;I would make this -2 like Python (// would then be consistent)
MsgBox(-3.0 // 2.0) ;-2.0

MsgBox(Integer(-3 / 2)) ;-1
MsgBox(Integer(-3.0 / 2.0)) ;-1

MsgBox(Floor(-3 / 2)) ;-2
MsgBox(Floor(-3.0 / 2.0)) ;-2
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
iseahound
Posts: 610
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: changing operators // and //= to only do integer or floor division

25 Sep 2018, 10:00

Guido explains why he uses floor division over integer division here: http://python-history.blogspot.com/2010 ... loors.html

Also, Ocaml is common and rare, depending on ones needs. It's a dialect of Caml, which is descended from ML (Meta Language). OCaml is notable for implementing Coq which is a theorem prover.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: changing operators // and //= to only do integer or floor division

09 Oct 2018, 15:53

- @iseahound: Great link thanks. It has some good reasons for why floor division (divide and round towards negative infinity) is more useful than integer division (divide and round towards zero).

- I was thinking that although // would be best for floor division, and is generally more useful. An operator for integer division could be useful also, e.g. to safely and succinctly convert a / b, which is integer division in many languages, when a and b are of integer type.
- Replacing operators with functions e.g. a%b to Mod(a,b) or / to Integer(a/b) can overcomplicate/lose the structure of a formula and can introduce new bugs. And you can get formulas worse than the example below.

Code: Select all

;from the AutoHotkey source code (util.cpp)
;C++:
(yday - (yday - wday + ISO_WEEK1_WDAY + ((366 / 7 + 2) * 7)) % 7 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);

;AHK:
(yday - Mod((yday - wday + ISO_WEEK1_WDAY + ((366 // 7 + 2) * 7)), 7) + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY)

;AHK (if we replace / with Integer() and /):
(yday - Mod((yday - wday + ISO_WEEK1_WDAY + ((Integer(366 / 7) + 2) * 7)), 7) + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY)
- Choosing an integer division symbol would be difficult. a idiv b if there isn't a better one.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: changing operators // and //= to only do integer or floor division

11 Mar 2019, 12:30

- If anyone had ever wondered about the odd behaviour of // in AHK v1, here's a summary.
- I would like // in AHK v2 to behave like // in Python 3.
- Btw you can use this link to run the Python 2/3 code:
Online editor and compiler
https://paiza.io/en

Code: Select all

normal division: x/y [float division, e.g. -3 / 2 = -1.5]
integer division: Integer(x/y) [round towards 0, e.g. Integer(-3 / 2) = Integer(-1.5) = -1]
floor division: Floor(x/y) [round down towards negative infinity, e.g. Floor(-3 / 2) = Floor(-1.5) = -2]

print(-3 / 2)
print(-3.0 / 2.0)
print(-3 // 2)
print(-3.0 // 2.0)

[Python 2]
-2 [floor division][different from Python 3]
-1.5 [normal division]
-2 [floor division]
-2.0 [floor division]

[Python 3]
-1.5 [normal division]
-1.5 [normal division]
-2 [floor division]
-2.0 [floor division]

[AHK v1]
-1.500000 [normal division]
-1.500000 [normal division]
-1 [integer division][different from Python 3]
-2.000000 [floor division]
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: changing operators // and //= to only do integer or floor division

06 Apr 2019, 04:47

A formula was mentioned on the GitHub PR, which I test here:

Code: Select all

;Changing operators // and //= to only do integer division. by HelgeffegleH · Pull Request #116 · Lexikos/AutoHotkey_L · GitHub
;https://github.com/Lexikos/AutoHotkey_L/pull/116
;(a//b) * b + Mod(a,b) = a ;where // is integer divide (unusual)
;(a//b) * b + FloorMod(a,b) = a ;where // is floor divide (more common)
;Int(a/b) * b + Mod(a,b) = a ;integer divide
;Floor(a/b) * b + FloorMod(a,b) = a ;floor divide

;AHK v2 script
q:: ;test formula (Mod and FloorMod)
Loop 100000
{
	;a := Random(-1000, 1000.0)
	;b := Random(-1000, 1000.0)
	a := Random(-1000, 1000) / 8
	b := Random(-1000, 1000) / 8
	if !a || !b
		continue

	vCalc1 := Floor(a/b) "*" b "+" JEE_FloorMod(a, b) "=" a
	vCalc2 := Integer(a/b) "*" b "+" Mod(a, b) "=" a
	MsgBox(vCalc1 "`r`n`r`n" vCalc2)

	;notify of any values that don't adhere to the formula
	if !(Floor(a/b) * b + JEE_FloorMod(a, b) = a)
		MsgBox("f:" A_Index "`r`n" a " " b)
	if !(Integer(a/b) * b + Mod(a, b) = a)
		MsgBox("i:" A_Index "`r`n" a " " b)
}
MsgBox("done")
return

;==================================================

;Math (Java Platform SE 8 )
;https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html

;result has the same sign as the divisor (or is 0)
;if vNum2 is positive, result is positive(/zero)
JEE_FloorMod(vNum1, vNum2)
{
	local
	;return vNum1 - ((vNum1 // vNum2) * vNum2) ;can give an incorrect answer
	return vNum1 - (Floor(vNum1 / vNum2) * vNum2)
}

;==================================================

I noticed here a proposal for <<< and >>> bitshift operators.
adding operators >>>, <<<, >>>= and <<<= by HelgeffegleH · Pull Request #135 · Lexikos/AutoHotkey_L · GitHub
https://github.com/Lexikos/AutoHotkey_L/pull/135

On that basis, meet the new floor divide and integer divide operators:
floor divide: // and //=
integer divide: /// and ///=
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
iseahound
Posts: 610
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: changing operators // and //= to only do integer or floor division

09 Apr 2019, 10:57

I'm sorry but no integer division. It's not even useful, and seems to be a relic from back when we had to cast types. If anyone needs Float -> Int try one of these operators Ceil(), Round(), Floor().

I think Guido explained it well when he said that Floor division is linked to the modulo operator.
I was asked (again) today to explain why integer division in Python returns the floor of the result instead of truncating towards zero like C.
...
But if one of the operands is negative, the result is floored, i.e., rounded away from zero (towards negative infinity):
...
If you want the relationship to extend for negative a (keeping b positive), you have two choices: if you truncate q towards zero, r will become negative, so that the invariant changes to 0 <= abs(r) < otherwise, you can floor q towards negative infinity, and the invariant remains 0 <= r < b.
Source: https://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: changing operators // and //= to only do integer or floor division

09 Apr 2019, 12:00

- Benefits of operators are: convenience, readability/understanding, maintainability, logic preservation, formula preservation/translatability.

- AutoIt, with its fewer operators, is very inconvenient.
Language Reference - Operators
https://www.autoitscript.com/autoit3/docs/intro/lang_operators.htm
Variables and Expressions - Definition & Usage | AutoHotkey
https://autohotkey.com/docs/Variables.htm#Operators

- It's very easy to wreck complicated formulas (introduce bugs) when you're forced to replace operators with function names and parentheses.
- Added functions names/parentheses can also obscure the logic.
- Also, you can convert from language A to B, then to C, and D, and it can get even worse! (I'm writing some functions across 6+ languages.)
- It's a strength of a language if it allows you to preserve formulas intact.
- One key problem is: you might try a fudge, e.g. if one language has int. div., and another has floor div., thereby creating in effect a different formula. Like a game of Chinese whispers.

- More operators?
- I've proposed an 'integer mod' operator, e.g. 'mod' (cf. % in C++ and AHK's Mod function). (Very useful for translation to/from other languages, and for AHK prototype code for machine code in C++ for AHK.)
- Perhaps we ought to consider a 'floor mod' operator also (cf. % in Python). (Always positive or zero for a positive divisor.)
- However, I'd also wondered about modifiable op1/op2 etc operators, based on user-defined binary functions, as a good catch-all solution.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: changing operators // and //= to only do integer or floor division

07 Jul 2020, 09:53

I think the risk of derailing this thread now is quite low, so I will make some selected comments, in an effort to reduce the misinformation and confusion which have gathered here.

Python has been mentioned several times but it seems you don't really understand what python's // do. Instead of making tests or try to find the answer on stack overflow, let's look at the documentation (!),
// wrote: floor division of integers results in an integer; the result is that of mathematical division with the ‘floor’ function applied to the result
src.
Note my bold, mathematical division is not the same as float division. Hence, in python, // doesn't do the equivalent of the ahk code floor(x/y), nor that of the python code math.floor(x/y). I showed an example on github, from which this should be clear, explicit,

Code: Select all

a := 5000000000000249856
b := 5000
msgbox floor(a/b) == a//b ; 0 

iseahound wrote: Guido explains why he uses floor division over integer division here: https://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html
jeeswg wrote: Great link thanks. It has some good reasons for why floor division (divide and round towards negative infinity) is more useful than integer division (divide and round towards zero).
No, he explains why
integer division in Python returns the floor of the result instead of truncating towards zero like C.
// does integer division in python, although they call it floor divison because that name matches their rounding (truncation). The reason they round this way is because it matches the behaviour of their modulo operator %. And then he gives some reason for why their modulo operator behaves as it does.
jeeswg wrote:- I would like // in AHK v2 to behave like // in Python 3.
We'd need to change our mod function too. These changes would complicate the implementation and degrade performance for no obvious benefit. Python added // to keep support for their integer division. The best answer I could find for why they extended the functionality to floats is
Motivation wrote: [...]
Another reason for this change is the desire to ultimately unify Python's numeric model. This is the subject of PEP 228 [0] (which is currently incomplete). A unified numeric model removes most of the user's need to be aware of different numerical types. This is good for beginners, but also takes away concerns about different numeric behavior for advanced programmers. (Of course, it won't remove concerns about numerical stability and accuracy.)

In a unified numeric model, the different types (int, long, float, complex, and possibly others, such as a new rational type) serve mostly as storage optimizations, and to some extent to indicate orthogonal properties such as inexactness or complexity. In a unified model, the integer 1 should be indistinguishable from the floating point number 1.0 (except for its inexactness), and both should behave the same in all numeric contexts. Clearly, in a unified numeric model, if a==b and c==d, a/c should equal b/d (taking some liberties due to rounding for inexact numbers), and since everybody agrees that 1.0/2.0 equals 0.5, 1/2 should also equal 0.5. Likewise, since 1//2 equals zero, 1.0//2.0 should also equal zero.
PEP 238 -- Changing the Division Operator
Disregarding that this unified numeric model was withdrawn, our numeric model is entirely different from python's. We need not support floats for this operator, but if we did, it shouldn't be floor(x/y). I showed a formula on github which will probably yield a correct integer result for floats. I have not found a good answer to what the meaning of python's // with floats with non-zero fractions is, eg, 2.5 // 3.4.
iseahound wrote:I'm sorry but no integer division. It's not even useful, and seems to be a relic from back when we had to cast types. If anyone needs Float -> Int try one of these operators Ceil(), Round(), Floor().
It is not a relic from anything, it is one of the basic operations for the integer types, if we are supposed to support an integer type, we must support the most basic operations. Float -> Int has nothing to do with this topic.
I'm against // because how would we do integer add, subtract, and multiply?
We support these operations with +, - and *.
jeeswg wrote: if you wanted to do integer division you could use Integer.

Code: Select all

MsgBox(Integer(-3 / 2)) ;-1
No, converting the result from true division to integer type does not in general yield the same result as doing integer division.

Code: Select all

a := 5000000000000249856
b := 5000
msgbox integer(a/b) == a//b ; 0
Cheers.
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: changing operators // and //= to only do integer or floor division

16 Jul 2020, 05:46

For V2-116 change, its arguable for // and //= operators to be restricted by a divisor type; we expect a quotient to be a fixed pointer number but why the divisor can't be a floating point number still? Now it flags

Code: Select all

10//2.5
as

Code: Select all

Error: Expected Integer but not a Float
But this might be the intention to get rounded 4 from this equation: divisor of 2 is too small and divisor of 3 is too big.
If someone wanted a divisor to be an integer he could use round(n) (floor(n), ceil(n)) or something like that.
Well, it remains manageable - old // method can be done with round(a/b).
I hope the community don't plan changing division by zero to produce infinity :D
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: changing operators // and //= to only do integer or floor division

16 Jul 2020, 07:48

Helgef wrote:
16 Jul 2020, 07:44
Old // did floor(a/b).
Cheers.
yeah, Floor is closer to discarding the remainder. =) I've seen ur post in the topic proving that Round's result may be different from Floor. :thumbup:
User avatar
vvhitevvizard
Posts: 405
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: changing operators // and //= to only do integer or floor division

16 Jul 2020, 08:47

After some thought, having restricted to fixed-point integers only division operator // is a good move. It enables better error checking. :thumbup:

Return to “AutoHotkey v2 Development”

Who is online

Users browsing this forum: No registered users and 1 guest