1. final message
- Posted by bill May 24, 2012
- 1721 views
I don't believe you guys will ever take any notice of what an outsider has to say, but..
These are thingns of some consequence:
Primary facts:
1 There is no multiplicative inverse of zero.
2 A Greatest Common Divisor has to:
. 1 be a divisor. ie it cannot be equal to zero.
. 2 be greater than any other divisor.
. Defining GCD(0,0) = 0 doesn't satisfy either
. condition 2.1 or 2.2.
No mathematical theory defines GCD(0,0) = 0.
The lattice theory article referenced defines
GCD(0,0) = 1 on the grounds that every integer is
divisible by 1. It doesn't satidfy 2.2.
Practical:
GCD(0,0) is given as 0 by a number of programming
languages because the Knuth algorithm would give
that result. Haskell gives it as undefined.
If used as a divisor it will likely produce an
exception or error. This would not necessarily occur
near where the exceptional result was produced.
There is, of course, the other difficulty that the
language may not have a value to return for
'not an integer'.
0/0:
Not indeterminate. See 1.
Can be defined to be any number with the consequence
of talking nonsense.
intdiv(-8,-3):
Dividing -8 envelopes into sets of maximum -3 is easy
1 set holds -8 envelopes. Not what you wanted?
-1 set holds 8 envelopes? - No you can't do that!
Perhaps I am wrong and you can do this. Show me!
Divide -8 envelopes into -3 sets, not so easy
-2 sets hold 3 envelopes, -1 set holds 2 envelopes or
-4 sets hold 2 envelopes, 1 set holds 0 envelopes.
At some time you guys are going to have to admit that
you are seriously talking shit.
2. Re: final message
- Posted by mattlewis (admin) May 24, 2012
- 1620 views
I don't believe you guys will ever take any notice of what an outsider has to say, but..
These are thingns of some consequence:
Primary facts:
1 There is no multiplicative inverse of zero.
2 A Greatest Common Divisor has to:
. 1 be a divisor. ie it cannot be equal to zero.
. 2 be greater than any other divisor.
. Defining GCD(0,0) = 0 doesn't satisfy either
. condition 2.1 or 2.2.
No mathematical theory defines GCD(0,0) = 0.
At some time you guys are going to have to admit that
you are seriously talking shit.
Here we go again. I'm not particularly passionate about this topic, but you have to do something with GDC(0, 0).
http://www.mathworks.com/help/techdoc/ref/gcd.html
By convention, gcd(0,0) returns a value of 0
They don't have a cited reference for this, but:
http://en.wikipedia.org/wiki/Greatest_common_divisor#Properties
It is useful to define gcd(0, 0) = 0 and lcm(0, 0) = 0 because then the natural numbers become a complete distributive lattice with gcd as meet and lcm as join operation. This extension of the definition is also compatible with the generalization for commutative rings given below.
I would agree from a purely mathematical standpoint, GCD(0, 0) is undefined. But defining it as zero seems like a reasonable and useful convention for a computer library function.
intdiv(-8,-3):
Dividing -8 envelopes into sets of maximum -3 is easy
1 set holds -8 envelopes. Not what you wanted?
-1 set holds 8 envelopes? - No you can't do that!
Perhaps I am wrong and you can do this. Show me!
Divide -8 envelopes into -3 sets, not so easy
-2 sets hold 3 envelopes, -1 set holds 2 envelopes or
-4 sets hold 2 envelopes, 1 set holds 0 envelopes.
I couldn't follow this bit. I'm not sure what you're trying to say. It seems to me that the return of intdiv(-8,-3) should be 2. I thought we decided that the intdiv in std/math.e was misnamed.
Matt
3. Re: final message
- Posted by jimcbrown (admin) May 24, 2012
- 1524 views
These are thingns of some consequence:
Primary facts:
1 There is no multiplicative inverse of zero.
Obviously true for basic arithmetic and so on. Simply false for certain mathematical systems (the trivial ring, wheel groups, etc.).
2 A Greatest Common Divisor has to:
. 1 be a divisor. ie it cannot be equal to zero.
. 2 be greater than any other divisor.
. Defining GCD(0,0) = 0 doesn't satisfy either
. condition 2.1 or 2.2.
No mathematical theory defines GCD(0,0) = 0.
The lattice theory article referenced defines
GCD(0,0) = 1 on the grounds that every integer is
divisible by 1. It doesn't satidfy 2.2.
Practical:
GCD(0,0) is given as 0 by a number of programming
languages because the Knuth algorithm would give
that result. Haskell gives it as undefined.
I admit that I'm skeptical with the broad claim you make that no mathematical theory defines GCD(0,0) = 0.
As a practical solution, GCD(0,0) = 0 makes sense to me. If nothing else, it's a simple and elegant way to signal to the caller that 0 was passed into GCD().
If used as a divisor it will likely produce an
exception or error. This would not necessarily occur
near where the exceptional result was produced.
I'd imagine that this would be the case most of the time. I can imagine a future version of the language (5.0 maybe) where, with strict_math turned on, an exception is thrown when GCD(0, 0) is called so these errors are caught immediately in programs that need it.
There is, of course, the other difficulty that the
language may not have a value to return for
'not an integer'.
Not sure if this complies with the IEEE spec, but we could always just return NaN.
0/0:
Not indeterminate. See 1.
I think you assume is true what you need to prove. 0/0 is indeterminate, as I have demonstrated elsewhere on this forum.
Can be defined to be any number with the consequence
of talking nonsense.
Or the trivial ring. Or as a simplification of the binomial theorem.
At some time you guys are going to have to admit that
you are seriously talking shit.
I don't believe you guys will ever take any notice of what an outsider has to say, but..
I think I can make a better case against you. Despite my constant and patient replies, you haven't as much as acknowledged my existence. Not to mention your constant attempts to belittle us (you could not think of a more politically correct term than "talking shit" ? Normally, I am sadden to see anyone leave these forums. However, considering your use of language and the misinformation you are trying to put out here, I am forced to admit that I'm quite glad to see you go.
4. Re: final message
- Posted by DerekParnell (admin) May 24, 2012
- 1464 views
I don't believe you guys will ever take any notice of what an outsider has to say, but..
What are you talking about? Where did you get that idea?
You cannot assume that "you guys" are all against you just because some disagree with your opinions. That attitude is not realistic.
These are thingns of some consequence:
Primary facts:
1 There is no multiplicative inverse of zero.
2 A Greatest Common Divisor has to:
. 1 be a divisor. ie it cannot be equal to zero.
. 2 be greater than any other divisor.
. Defining GCD(0,0) = 0 doesn't satisfy either
. condition 2.1 or 2.2.
No mathematical theory defines GCD(0,0) = 0.
The lattice theory article referenced defines
GCD(0,0) = 1 on the grounds that every integer is
divisible by 1. It doesn't satidfy 2.2.
Practical:
GCD(0,0) is given as 0 by a number of programming
languages because the Knuth algorithm would give
that result. Haskell gives it as undefined.
If used as a divisor it will likely produce an
exception or error. This would not necessarily occur
near where the exceptional result was produced.
There is, of course, the other difficulty that the
language may not have a value to return for
'not an integer'.
0/0:
Not indeterminate. See 1.
Can be defined to be any number with the consequence
of talking nonsense.
We are limited to the constraints of the programming language we are working with. As such, we have chosen that under some circumstances GCD() might not return a divisor. When the result of GCD() is not possible, we have decided to return 0 as a way to alert the calling code that something exceptional might have to be done.
We agree that GCD(0, x) where x != 0, returns abs(x), because that is the greatest number that divides into both 0 and x.
We agree that GCD(0, 0) is a special case. As every number (except 0) can divide into 0, the greatest divisor approaches infinity and thus cannot be determined. In this case, we have our GCD() function also return 0 to alert the calling code that something maybe wrong with the inputs to the function.
If Euphoria supported Exceptions, the we could have it raise an exception in this case, but we can't do that (yet) so a the function returns a special value (0) to indicate an exception.
intdiv(-8,-3):
Dividing -8 envelopes into sets of maximum -3 is easy
1 set holds -8 envelopes. Not what you wanted?
-1 set holds 8 envelopes? - No you can't do that!
Perhaps I am wrong and you can do this. Show me!
Divide -8 envelopes into -3 sets, not so easy
-2 sets hold 3 envelopes, -1 set holds 2 envelopes or
-4 sets hold 2 envelopes, 1 set holds 0 envelopes.
At some time you guys are going to have to admit that
you are seriously talking shit.
It is easy to get distracted here, but this function is working with magnitudes, not envelopes or any other units-of-measure. The UOM question is one that the standard library leaves for the calling code to work with.
The difference between intdiv() and div() is that the intdiv() result is always an integer.
So, div(-8, -3) gives 2.666666666666666... thus intdiv() needs to return this result but as an integer. The discussion is whether it should floor(), ceil(), or round() the result. It could be argued that the behaviour to take would depend on the reason the function is being called, but that is clearly in the domain of the calling code and intdiv() should be agnostic about why it is being called.
Sometimes we might want to know the maximum number of sets needed to contain all the items being divided; in which case ceil() is useful. However, sometimes we might be trying to find the number of complete sets needed; in which case floor() is better. I'm not sure why one would need to round() the div() result but there could be a valid use-case for that.
So, maybe we we need is to have intdiv() accept a third argument, that tells it how to handle the result of div() before returning. I would like to see ceil() be the default behaviour if the third argument was omitted, but that's negotiable.
Now it does get interesting when the arguments have different signs. div(-8, 3) and div(8, -3) give -2.666666666... So what should intdiv() do here? I'm thinking that we just keep the metaphor of intdiv() returning a number of sets in which case, it would always return a non-negative result. In other words, it should just ignore the arguments' signs.
5. Re: final message
- Posted by mattlewis (admin) May 24, 2012
- 1523 views
intdiv(-8,-3):
It is easy to get distracted here, but this function is working with magnitudes, not envelopes or any other units-of-measure. The UOM question is one that the standard library leaves for the calling code to work with.
The difference between intdiv() and div() is that the intdiv() result is always an integer.
So, div(-8, -3) gives 2.666666666666666... thus intdiv() needs to return this result but as an integer. The discussion is whether it should floor(), ceil(), or round() the result. It could be argued that the behaviour to take would depend on the reason the function is being called, but that is clearly in the domain of the calling code and intdiv() should be agnostic about why it is being called.
Sometimes we might want to know the maximum number of sets needed to contain all the items being divided; in which case ceil() is useful. However, sometimes we might be trying to find the number of complete sets needed; in which case floor() is better. I'm not sure why one would need to round() the div() result but there could be a valid use-case for that.
So, maybe we we need is to have intdiv() accept a third argument, that tells it how to handle the result of div() before returning. I would like to see ceil() be the default behaviour if the third argument was omitted, but that's negotiable.
Now it does get interesting when the arguments have different signs. div(-8, 3) and div(8, -3) give -2.666666666... So what should intdiv() do here? I'm thinking that we just keep the metaphor of intdiv() returning a number of sets in which case, it would always return a non-negative result. In other words, it should just ignore the arguments' signs.
When I think of integer division, I'm reminded of my elementary school adventures in long division, and the answer should be the quotient, discarding the remainder. Looking at it, it's not immediately obvious to me why (or what for) I'd want to use math:intdiv(). This may simply be conceptual blindness due to my familiarity with integer division as common in other programming languages.
Maybe we could have a version that returns { quotient, remainder }.
I would assume that it would use floor() to go from floating point to integers, and that there should be no need for special sign manipulation.
My expectation (just given the name) would be an implementation of:
public function intdiv(object a, object b) return floor( floor(a)/ floor(b) ) end function
...and then maybe...
public function intdivr(object a, object b) object c = floor( floor(a)/ floor(b) ) return { c, a - (b*c) } end function
Matt
6. Re: final message
- Posted by EUWX May 24, 2012
- 1492 views
I can imagine a future version of the language (5.0 maybe) where, with strict_math turned on, an exception is thrown when GCD(0, 0) is called so these errors are caught immediately in programs that need it.
Without getting into details, I get the impression that there are two or even three interpretations or answers to these particular derivatives of a divide by 0. Where there is no agreement of interpretation, or even to allow a minority interpretation, a greater use of flags in "settings" is desirable.
I am using generic syntax in the following:
set_number_system_to decimal_integer
set_number_system_to hex_integer
set_number_system_to decimal
Through our various programming methods we allow use of integers, decimals, and hex and binary. We need the variations badly so we create explicit ways of doing the above. Theoretically we could have system settings available to be used as defaults and changed during a program. For frequently used changes in the number system, it would become too cumbersome.
Coming back to jimcbrown's suggestion above, one cannot fail to see the logic of his practical solution, allowing the programmer to decide what interpretation he would like in his work. Sometimes a practical approach to a rather complex computing problem is the best approach.
7. Re: final message
- Posted by DerekParnell (admin) May 24, 2012
- 1494 views
My expectation (just given the name) would be an implementation of:
public function intdiv(object a, object b) return floor( floor(a)/ floor(b) ) end function
...and then maybe...
public function intdivr(object a, object b) object c = floor( floor(a)/ floor(b) ) return { c, a - (b*c) } end function
And mine would more like ...
public function intdiv(object a, object b, integer behave = 1) object t t = abs(a) / abs(b) switch behave do case -1 then return floor(t) case 0 then return round(t) case 1 then return ceil(t) case else fail("Unknown behaviour requested") end switch end function ? intdiv(-8, -3, 1) --> 3 ? intdiv(-8, -3, 0) --> 3 ? intdiv(-8, -3,-1) --> 2
8. Re: final message
- Posted by mattlewis (admin) May 24, 2012
- 1450 views
And mine would more like ...
public function intdiv(object a, object b, integer behave = 1) object t t = abs(a) / abs(b) switch behave do case -1 then return floor(t) case 0 then return round(t) case 1 then return ceil(t) case else fail("Unknown behaviour requested") end switch end function ? intdiv(-8, -3, 1) --> 3 ? intdiv(-8, -3, 0) --> 3 ? intdiv(-8, -3,-1) --> 2
I can see the value in different rounding methods, but the sign handling here seems wrong, as I would expect:
intdiv(-8, 3, 0) --> -2
Actually, to correct my earlier statement...instead of floor(), I think trunc() is more appropriate, as it does what I would expect integer division to do.
Matt
9. Re: final message
- Posted by DerekParnell (admin) May 25, 2012
- 1446 views
I can see the value in different rounding methods, but the sign handling here seems wrong, as I would expect:
intdiv(-8, 3, 0) --> -2
Ok, I'm not wedded to abs() in this case. So how about ...
public function intdiv(object a, object b, integer behave = 1) object t t = abs(a) / abs(b) switch behave do case -1 then t = floor(t) -- Move towards zero. case 0 then t = round(t) -- Move either way to round case 1 then t = ceil(t) -- Move away from zero case else fail("Unknown behaviour requested") end switch return t * sign(a) * sign(b) -- Adjust sign for each element in arguments. end function ? intdiv({-8,8}, -3, 1) --> {3,-3} ? intdiv({-8,8}, -3, 0) --> {3,-3} ? intdiv({-8,8}, -3,-1) --> {2,-2}
10. Re: final message
- Posted by mattlewis (admin) May 25, 2012
- 1367 views
I can see the value in different rounding methods, but the sign handling here seems wrong, as I would expect:
intdiv(-8, 3, 0) --> -2
Ok, I'm not wedded to abs() in this case. So how about ...
public function intdiv(object a, object b, integer behave = 1) object t t = abs(a) / abs(b) switch behave do case -1 then t = floor(t) -- Move towards zero. case 0 then t = round(t) -- Move either way to round case 1 then t = ceil(t) -- Move away from zero case else fail("Unknown behaviour requested") end switch return t * sign(a) * sign(b) -- Adjust sign for each element in arguments. end function ? intdiv({-8,8}, -3, 1) --> {3,-3} ? intdiv({-8,8}, -3, 0) --> {3,-3} ? intdiv({-8,8}, -3,-1) --> {2,-2}
Doing the abs() and then multiplying by signs offends my sense of efficiency.
Matt