1. final message

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.

new topic     » topic index » view message » categorize

2. Re: final message

bill said...

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).

MATLAB said...

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:

Wikipedia said...

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.

bill said...

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

new topic     » goto parent     » topic index » view message » categorize

3. Re: final message

bill said...

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.).

bill said...

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().

bill said...

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.

bill said...

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.

bill said...

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.

bill said...

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.

bill said...

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.

new topic     » goto parent     » topic index » view message » categorize

4. Re: final message

bill said...

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.

bill said...

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.

bill said...

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.

new topic     » goto parent     » topic index » view message » categorize

5. Re: final message

DerekParnell said...
bill said...

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

new topic     » goto parent     » topic index » view message » categorize

6. Re: final message

jimcbrown said...

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.

new topic     » goto parent     » topic index » view message » categorize

7. Re: final message

mattlewis said...

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 
new topic     » goto parent     » topic index » view message » categorize

8. Re: final message

DerekParnell said...

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

new topic     » goto parent     » topic index » view message » categorize

9. Re: final message

mattlewis said...

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} 
new topic     » goto parent     » topic index » view message » categorize

10. Re: final message

DerekParnell said...
mattlewis said...

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. smile

Matt

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu