
1/0 = 0 - ingve
https://www.hillelwayne.com/post/divide-by-zero/
======
whack
My problem with "1/0 = 0" is that it's essentially masking what's almost
always a bug in your program. If you have a program that's performing divide-
by-zeroes, that's almost surely something you did not intend for. It's a
corner case that you failed to anticipate and plan for. And because you didn't
plan for it, whatever result you get for 1/0 is almost surely a result that
you wouldn't want to have returned to the user.

When encountering such unanticipated corner cases, it's almost always better
to throw an error. That prevents any further data/state corruption from
happening. It prevents your user from getting back a bad result which she
thinks she can trust and rely on. It highlights the problem very clearly, so
that you know you have a problem, and that you have to fix it. Simply
returning a 0 does the exact opposite.

If you're one of the 0.1% who did anticipate all this, and correctly intended
for your program to treat 1/0 as 0, then just check for this case explicitly
and make it behave the way you wanted. The authors of pony are welcome to
design their language any way they want. But in this case, they are hurting
their users far more than they are helping.

~~~
bunderbunder
I almost want two different division operations: One where 1/0 = 0,
exclusively for use in progress bars and stuff like that, and another one for
everything else.

Because frequently division by zero indicates a bug. But similarly frequently,
I end up crapping out annoying little bits of code like

    
    
      if (foo == 0):
        return 0
      else:
        return bar / foo

~~~
simias
I'm reading the "Pony" tweet quoted in TFA and your comment and I'm left very
puzzled: is that really that common to want x / 0 == 0 ? In practice where
does that crop up?

You say that you frequently have to write your little shim but honestly I
don't remember writing code like that in recent memory.

You talk about progress bars, I suppose it makes sense if you somehow try to
copy 0 elements for instance, and you end up dividing by zero when computing
the progress, like:

    
    
        pos_percent = (copied_elems * 100) / total_elems
    

And both copied_elems and total_elems are zero. But in this case wouldn't you
want the computation to return 100% instead of zero?

It's also a bit odd because it introduces a discontinuity: as the divisor goes
towards zero the result of the operation gets greater until it reaches exactly
zero and it yields 0. Wouldn't it make more sense to return INT_MAX (for
integers) or +inf for floats? If you're writing a game for instance it might
work better.

I guess it just goes to show that it probably makes a lot of sense to leave it
undefined and let people write their own wrapper if necessary to do what works
best for them in their given scenario.

~~~
huehehue
Practically, it's quite common to not immediately know the divisor. In cases
where the divisor is initially unknown but takes an imperceptible amount of
time to compute it's better to render 0%. Otherwise you might get a flash of a
full progress bar (for example) while the divisor is determined.

Of course, it's context dependent. As others mention, your code might be full
of stuff like _X / (divisor || 1)_.

~~~
user5994461

        X / (divisor || 1).
    

It's invalid code in C, C++ and Java.

~~~
l_t
Boolean operators returning values is common, especially in dynamically typed
languages. The code is valid in JavaScript, for example, and in Python (except
it uses "or" instead of "||").

~~~
user5994461
In python, it should probably be corrected with // or 1.0 to make it either an
integer division or a float division.

~~~
l_t
Ah, that's true. Good point.

------
spooneybarger
Hi,

I'm on the Pony core team. I will be writing in more detail about this
decision. A few short notes until then:

1) no one on the team has ever been happy with ending up here, understanding
why the decision was made involved understand how partial functions (one that
can produce errors like division by zero) are handled in Pony and interesting
ergonomic issues that can result that is a large part of what my post will be
about.

2) this applies only to integer division wherein division by zero is
undefined. 1.0/0.0 uses the available Infinity value.

3) Partial function math is coming to Pony that includes 1/0 as partial (ie
error producing) as well as handling integer overflow and underflow for
operations: `+`, `-`, and `*`.

4) It's very straightforward even without that those operations to define your
own division that will be partial (ie return an error) for division by zero.

Edit to include link to the comment below because it contains a good bit of
the decisions that have to make when dealing with integer math:

[https://news.ycombinator.com/item?id=17736637](https://news.ycombinator.com/item?id=17736637)

Which is part of what I will touch on in my post about the decision process
that Pony went through to reach to state we are currently at (which I want to
highlight, is one we intend to improve- see #3 above).

~~~
thanatos_dem
> 2) this applies only to integer division wherein division by zero is
> undefined. 1.0/0.0 uses the available Infinity value.

Oh jeeze... to me that almost nullifies all of the points in the article. It
does an alright job explaining how 1/0 = 0 is at least consistent with other
notions in the language, but to hear that the same logic can’t be applied to
floats is just... well, objectively it’s a mess.

~~~
spooneybarger
Hillel is talking about math. Unfortunately computers don't really do "math".
For example, math doesn't have overflow and underflow to deal with.

The floating point standard says that division by 0.0 should be Infinity and
provides a value for it. The integer math, all possible values are used for
numbers, so division by zero is undefined behavior.

And from there, every language is potentially going to have a mess of
inconsistency to deal with.

You can make 1/0 = Infinity so long as you box all your integers. That is, its
not using the machine type, but I type that is a wrapper that can be the
machine type or Infinity. And every user takes a large performance hit even if
they will never divide by zero.

For some languages boxing integers is not a bad thing because they already do
it. Why do they do it? Usually, because of another not math problem. Overflow
and underflow:

What is 0 - 1? Well, its -1 right? Except of course if you have an unsigned
integer, then its the max value of the integer. And what if you had 1 to the
max value that the computer can represent? You wrap around. Some languages
make all integers protect you from this and take a performance hit to be able
to box and be able to represent numbers better as we expect them to work. In
return, you can not do integer math as fast as you could.

Computers and numbers... its an inconsistent mess and a series of tradeoffs
for any language of performance and various possible errors.

I'm going to talk about this and more in my post.

~~~
starmole
Integers are perfectly fine in math. But they are not a field. Integers modulo
something are also well understood in math - but again not a field.

~~~
spacehome
Integers modulo any prime are a field.

~~~
ummonk
Powers of 2 are not a prime though, unless the power is 1 (i.e. we are dealing
with single-bit integers).

------
phyzome
Some people say "oh, that's easy, 1/0 is +Infinity". So the real fun is at
0/0.

The limit of x/y as x and y go to zero depends on _which path_ across the xy
plane you take towards the singularity. Along one approach, the limit is 0,
along another approach the limit diverges to infinity, along yet another the
limit is 17.

I'm not kidding! Go to
[https://www.geogebra.org/3d](https://www.geogebra.org/3d) and enter "x/y" and
spin the graph around. The "value" at x=0 y=0 is the entirety of the z-axis.

For another perspective, try
[http://www.wolframalpha.com/input/?i=z%3Dx%2Fy](http://www.wolframalpha.com/input/?i=z%3Dx%2Fy)
and turn on contour mode for the 3D plot. Notice how the contour lines radiate
out from the z-axis; each of those is an "approach" to the singularity at a
different z-value, and taking the limit along each line leads to a different
value.

~~~
wodenokoto
I always thought division by zero was, at best, + and - infinity, depending on
the path, which is why we leave it undefined.

How would a path lead to 17?

~~~
phyzome

      x=170, y=10
      x=17, y=1
      x=1.7, y=0.1
      x=0.17, y=0.01
    

The answer keeps being 17, even as x and y both get vanishingly close to zero.

I encourage you to play around with a 3D graphing calculator and see all the
different paths you can take along that surface to reach the singularity. They
all "reach" it at different heights.

~~~
DoctorOetker
you are explaining why 0 / 0 can approach 17, this is much less controversial,
and is often considered the bottom element...

~~~
Jaxan
17 is a bottom element?

~~~
jibal
That's not what he said.

------
luso_brazilian
_> But is Pony doing something unsound? Absolutely not. It is totally fine to
define 1/0 = 0. Nothing breaks_

It actually does break something, the symmetry between division and
multiplication and the many pieces of code that assume that (x / y) * y equals
x. Here is a naive and non practical example, but it is not impossible to find
a real world example where this simplified code manifests itself accidentally
or by design

    
    
      function do_something_with_x(x, y) {
        let ratio = x / y;
        if (do_something_with_ratio(ratio)) {
          return x * y;
        }
        else return null;
      }
    

Again, this is a naive example but one that could manifest itself with a very
imprecise result when y = 0

~~~
ballenf
What if number types were Optionals after any operation that could result in
any kind of unusual number (sqrt(-1), Infinity, NaN)? Or maybe after every
operation, since any operation could overflow the type.

Do any languages do that? Seems more consistent (if _way_ more hassle) than
giving a mathematically false result out of pragmatism. At least in a strictly
typed language.

~~~
zokier
Isn't that essentially what floats already are? A sum type of numbers,
infinities, and NaN(s).

~~~
Someone
Yes and no. I think the OP is looking for a strongly typed language where you
can’t do any operation on that sum type, forcing you to check results after
every operation.

------
hyperpape
This thread is showing once again that reading comprehension is not our
strong-suit here on HN.

The author does not once say that Pony's choice is a good one, only that
whether it is a good or bad one should be settled by engineering consequences,
and that there is no purely mathematical argument that precludes it.

I can't help but think it _is_ a bad idea, because it's easier to overlook a 0
appearing than a NaN. That argument isn't math, though.

~~~
rcoveson
The Pony devs did chime in and mentioned that they do define division by zero
to be NaN (or positive infinity) where the underlying type supports it (e.g.
IEEE 754 floats).

Most integer representations have no space for such a value, so the only
choices available to language developers are:

1\. Throw an exception or otherwise consider it an error

2\. Define the result to be 0 or 1 or some other integer value (0 being the
only good choice)

3\. Use a non-standard integer representation

Most languages opt for option 1, Pony chose 2, and I've never seen 3, perhaps
due to it requiring so much software interference and precluding inter-
operation with other languages.

~~~
otabdeveloper2
> 0 being the only good choice

Devil's advocate: why not a maximum integer like 18446744073709551615 or
9223372036854775807?

0 looks like a valid number, while 18446744073709551615 is an obvious NaN for
any programmer looking at the output.

~~~
spooneybarger
Pony core team member here.

In some domains it might be. In others it might not. It's no more right or
wrong in my mind.

I think the size of the integer needs to be considered in your thinking as
well:

If you have unsigned 8 bit integers, the max value is 255, is that really
going seem NaN? How about 127 for a signed 8 bit integer?

And, should the result of division by zero vary based on the bit size of the
integer? That's a discussion unto itself.

------
excalibur
> We’ve now established that if we choose some constant C, then defining
> division such that x/0 = C does not lead to any inconsistencies.

No, you haven't. You've merely failed to locate any. You've said "I'm not
going to prove that this works. I'm going to assume that it does and act as if
it did, and place the burden on you to prove otherwise."

~~~
JadeNB
> No, you haven't. You've merely failed to locate any. You've said "I'm not
> going to prove that this works. I'm going to assume that it does and act as
> if it did, and place the burden on you to prove otherwise."

Excellent point. It's not even known if we can get any inconsistencies
_without_ making this definition; and it's known that, if it's true that we
can't get any inconsistencies without it, then we can't prove that it's true.
Building on such possibly shaky foundations can't make them stronger.

~~~
JadeNB
(That's not mathematical maundering, by the way; it is a correct if informal
statement of part of the incompleteness theorems. I appreciated excalibur
([https://news.ycombinator.com/item?id=17736486](https://news.ycombinator.com/item?id=17736486)
)'s point, and wanted to underline the significant, and mathematically
precise, difference between "one apparent inconsistency is not present" and
"there is no inconsistency.")

------
banachtarski
This article grinds my gears. He quotes a number of mathematicians that
correctly state the undefined nature of 1/0\. Then proceeds to interpret that
this means that we can choose any _specific_ value to represent as 1/0 that we
want. NO. We have "NaN" for a reason and it is an important signal to the
programmer that a mistake was made. The language that assigns it to 0 silently
is bunk as is this article.

~~~
repsilat
> correctly state the undefined nature of 1/0

Erm, when we say it's "undefined" we mean it literally -- standard
mathematical systems of arithmetic do not define a value for that division.

If you make another system of arithmetic you can define it how you want and be
consistent with "regular maths" for the operations in which things _are_
defined. It's an extension.

> We have "NaN" for a reason

Funnily enough, IEEE754 defines 1/0 as positive infinity, not Nan. But none of
these things are "the truth" in any reasonable sense of the word, just "useful
systems".

Defining it as 0 at least means floating point numbers are (presumably) closed
under arithmetic operations, which could be handy.

~~~
chess19
Standard mathematical systems of arithmetic do not permit a reasonable
definition of 1/0.

Mathematicians define equality of fractions by stating that a/b = c/d if and
only if a·d = b·c. This means that if we define 1/0 = 1 then 0 = 1.

To be fair, this is perfectly consistent, except everything in our system is
equal to zero.

~~~
a_wild_dandan
> Mathematicians define equality of fractions by stating that a/b = c/d if and
> only if a·d = b·c. This means that if we define 1/0 = 1 then 0 = 1.

That's not implied, so far as I can tell.

a / b = 1 / 0, thus

a * d = b * c => 1 * d = 0 * c => d = 0

So all you can say is that d = 0, or at most that c / 0 = 0. Is there some
extra step you're taking?

~~~
boyce
So if 1·d = 0·c, write 1 in terms of the other elements and then evaluate.

------
Hasz
My two issue with this is it totally relies on a specially constructed
definition, and it leads to unintuitive results.

The issue with special definitions is you can use them to say anything you
want, turning regular, common operations into weirdness.

What does it mean to take a factorial on the real numbers, or to add only on
the even integers? In both cases, we're twisting what are generally accepted
mechanics and domains into something else to get a funny result, like 1/0 = 0.

He gets to that point here:

" We can say that division’s domain is all the real numbers except zero. This
is what we do in our day-to-day lives, and the way that Agda and Idris handle
division. We can choose some value that isn’t a real number, such as
“undefined” or infinity, and say x/0 = <whatever>. This is what some
mathematicians do with the Riemann sphere. We could choose some real number,
like 19, and say that x/0 = 19. This is what Isabelle, Lean and Coq do.

"

So, tiny change in definition --> big change in outcome.

*I'm an undergrad

~~~
colechristensen
You may not be familiar but a "factorial on the real numbers" is the gamma
function and it has all sorts of useful applications. (it works on real and
complex numbers except for non-positive integers)

~~~
chess19
The concerned reader might wonder how it is possible to assert that there is
_one_ correct definition of an extension of the factorial function to the
real/complex numbers. Why is the gamma function better than any other
extension?

The answer is that the gamma function is the unique logarithmically convex
extension of the factorial function.

~~~
a_wild_dandan
There ISN'T one correct extension of a factorial function.

The properties of the standard gamma function are great, but some might prefer
the properties of Hadamard's or Luschny's alternative gamma function.

Like many arbitrary extensions in mathematics -- be it the factorial function
or the division function which deals with 1 / 0 differently -- it's a matter
of taste and convenience!

Interestingly the arbitrariness of some mathematical choices seem to unnerve
folks on an almost existential level. My guess is that it conflicts with their
expectation of capital T truth from mathematics.

------
c3534l
Edit: I guess there's a reason I'm not a language designer.

I've always thought that programming languages should have a nonzero number
class in the vein of unsigned and float and that division should only be
defined with a nonzero number class as the denominator. To divide a 64-bit
float by another float, you'd have to either specify it as nonzero in the type
or convert it somehow. Make division by zero impossible with the type-checker.

Setting your programming language to evaluate x/0 = 0 seems evil. You're
taking a bug in the programmers code and then hiding the fact that something
logically unsound happened and in a way that would be very difficult to debug
or detect.

In fact, this is what happens when C# think it's being clever by returning
infinity as the result of a division operation (which isn't even a number).
It's a bug that winds up infecting every function that relies on that code
without ever throwing an error.

A programming language shouldn't return NaN or Infinity or anything like that
when it encounters division by zero. It should demand you use error-handling
or ensure it can't happen. If it does happen, it should tell you exactly where
the problem occurred and not assume that some arbitrary value will work just
as well.

~~~
spooneybarger
Hi,

I'm on the Pony core team and I generally agree with you. The problem is, if
you want to allow people to write high performance code, you are penalizing
them becaues, for floating point:

1.0/0.0 is infinity. That's not C# being clever. That's C# following the
floating point standard and using the math that the computer provides. To not
use that standard means that you make every use of division slower, even if
the programmer has in some way assert and otherwise knows that that they won't
be dividing by zero.

Note that 1/0 is integer math and for that there is no standard and its
undefined behavior. You can't return NaN or Infinity for that without boxing
numbers which is a performance hit and would be penalizing programmers who
want/need to go as fast as possible.

~~~
skybrian
I'm curious, what do you think about Julia's approach with its special
"missing" value? Does this approach make sense outside the context of data
analysis?

[https://julialang.org/blog/2018/06/missing](https://julialang.org/blog/2018/06/missing)

~~~
spooneybarger
I can't really comment. I don't know how they are doing it and why they made
that choice. I assume that Julia was already boxing integers in some fashion
at which point this 100% makes sense to me.

Also, given the performance profile that you are seeking to allow programmers
to achieve, I think boxing all integers makes sense, then you can give folks
protection from integer overflow and underflow and otherwise make how the
computer does math more closely approximate what we expect from doing math.

I think that following my above reasoning that only having floating point math
can also make sense. That is... in most programming languages 3 and 3.0 are
different. Such that 3/ 2 = 1 and 3.0/2.0 = 1.5.

We allow for 3/2=1 because, integer math is faster than floating point math
and we want to allow folks to go as fast as possible when doing things like
addition, subtraction and multiplication and accept that we can't represent
all the numbers that come from division and give an approximation.

~~~
ChrisRackauckas
Julia doesn't box integers, that would destroy speed. It also doesn't protect
from overflow/underflow. It specializes on Vector{Int} so that's it's just a
standard vector of integers. Then Vector{Union{Int,Missing}} is stored in
memory as a vector of integers with a bitarray declaring missings. Indexing
operations are expanded to ifelse a check for the existence and then return
the value if it exists or a missing. Then branches are added by the compiler
to handle the small unions. This keeps pure integer use without overhead, and
gives a small penalty when using missing (which doesn't turn out to be all
that bad due to how pipelining is usually done), but it's safe and any type
can have missing values.

~~~
spooneybarger
Thank you. I look forward into learning more about how Julia handles this.

------
halflings
Unlike what the author says, this is the total opposite to a
practical/pragmatic solution.

He does not prove that this is a useful representation, only that given his
own axioms, this can be considered mathematically correct.

Very practical issues with 1/0 == 0:

\- This result is counter-intuitive, took building a custom fields and
responding to the incredulity of all. \- The main reason this is counter-
intuitive is not mentionned in the post: division is no longer monotonous.

1/0.5 = 2 1/0.25 = 4 1/0.0001 = 10000 1/0 = 0

This is calling for an Ariane 5-type crash because an underflow error caused a
value to suddenly fall from 10e6 to 0.

~~~
stringer
Were are speaking of integers here not FP numbers.

~~~
curice
Not to be pedantic, but one of the author's own examples involves pi inverse,
so I think discussing FP numbers is valid.

~~~
stringer
Yes I know, but in the context of Pony, 1/0==0 only applies to integers, not
FP numbers. The article doesn't make it clear.

------
hpcjoe
Hrm ... argumentation by reference to authority (various Ph.D. people) is a
sure way to lose a scientific argument.

But that isn't my only qualm.

In the construction of the fields, there is a simple definition of the
division function. It is intrinsically the solution of a = r * b, where r is
the unknown. If a is nonzero, and b is zero, then r, the ratio, is said not to
exist. Put another way, there is no real value of r that can be chosen that
satisfies r * 0 = a. See [1] for example, as 0 is not an invertible element of
the field over the reals.

So ... I can't say I agree with their choice of 1/0 == 0. They may be free to
choose any value they wish, but then from an aesthetic viewpoint, do they
really want to surprise the user?

[1]
[https://en.wikipedia.org/wiki/Multiplicative_group](https://en.wikipedia.org/wiki/Multiplicative_group)

~~~
ummonk
>In the construction of the fields, there is a simple definition of the
division function. It is intrinsically the solution of a = r * b, where r is
the unknown. If a is nonzero, and b is zero, then r, the ratio, is said not to
exist. Put another way, there is no real value of r that can be chosen that
satisfies r * 0 = a.

Exactly. That's the definition of division. Here, he is introducing a totally
different definition and claiming it isn't wrong because it is consistent. I
mean, by his logic I could define division as a/b := a-b and claim it is
consistent and therefore not wrong, but that is obviously not division...

------
throwawaymath
_" Mathematics does not give us truths, it gives us consequences."_

I'd like to point out that, as I stated in another comment in this thread, the
author's supposed refutation of the inconsistency inherent in division by zero
within fields is incorrect. Their refutation is as follows:

 _The problem is in step (3): our division theorem is only valid for c ≠ 0, so
you can’t go from 1 /0 _ 0 to 1 * 0/0\. The “denominator is nonzero” clause
prevents us from taking our definition and reaching this contradiction.*

This is a strawman, and it's not the way a formal proof that division by zero
_in fields_ is undefined would proceed. First and foremost, the conceptual
purpose of the proof is to demonstrate that you cannot define division by zero
while still retaining the algebraic structure of a field. Trying to refute
this point by stating that the proof cannot make use of division by 0 is
begging the question. The whole point is that the proof shows you any way you
define division by 0 is going to compromise your definition of a field, _or_
it's going to make fields with nonzero elements impossible.

What the author provided is a very contrived strawman for refutation that
belies the actual point. You _can_ define division by zero if you'd like, by
using wheels, or extended number systems based on fields (i.e. positive and
negativie infinities in the extended Real number system), but you _cannot_ do
it using fields. In fact, the modern, axiomatic definition of a field
explicitly excludes the _unit_ 0 from the otherwise sane rules of
multiplicative inverses.

More generally, I'd like to make a couple of observations from both a
philosophical and a practical standpoint. First, mathematics does not give us
true statements about the world, it gives us _consequences_ that must follow
if we accept various axioms or definitions. You can define division by 0 if
you'd like, and you can even do so in a sane and useful way. But you will not
have a field. But _much more importantly_ , it's conceptually unsound to base
an argument about the practical, programmatic behavior of an undefined
operation based on imperfect arguments about abstract mathematics. Technically
speaking, computers don't even deal with real numbers. If you find yourself
mounting a defense of your programming language's behavior by running through
the first lecture of a real analysis or linear algebra course, something has
gone very wrong with your enterprise.

~~~
antidesitter
_First, mathematics does not give us true statements about the world, it gives
us consequences that must follow if we accept various axioms or definitions._

Isn't a consequence in itself a true statement?

~~~
throwawaymath
Allow me to clarify that point. The idea is that - conceptually speaking -
mathematics cannot be used to tell you empirical _axioms_ about the world in
which we reside. All it can do is tell you what _must_ be true given certain
well-defined assumptions. It is a phenomenally powerful tool for proving
things about the world _from_ empirical axioms, but _which_ empirical axioms
we choose to rely on in engineering is mostly the domain of physics or the
sciences.

The underlying point here is mostly a philosophical one, but it has some
bearing on the matter at hand. In effect, the definition (or lack thereof) for
division by zero in _fields_ is of no practical consequence for the real world
impact of implementing an operation which admits division by zero. I can
define an algebraic structure in which division by zero is sane (it _is not_
in fields, despite what the article states!), or I can define an algebraic
structure in which division by zero is insane. Both can be coherent,
consistent and genuinely useful.

But whether or not I can define something that works has nothing to do with
what happens "when the rubber meets the road", so to speak. It was a mistake
to open up an argument about programming division by 0 using the field axioms
in the first place. There is no "one truth", there are only facts which must
follow as consequences from assumptions. This is especially the case for
programming, considering that computers are fundamentally incapable of working
with real numbers in the first place.

------
ivanech
I'm not seeing how the tweet is mocking the Pony developers. It seems to
mirror the tone and the content of of the documentation in the screenshot. It
looks like an absurdist spin on the ivory tower vs industry meme, and it
doesn't make anyone the butt of the joke.

~~~
spooneybarger
The screenshot in question cut off the explaination of why. I'm one of the
Pony developers and I took it to be mocking.

~~~
ivanech
Thanks for replying! I took a look at the thread in question and you're
totally right. In context, this is unambiguously snide. I've been fortunate
that my learning and working environments have been absolutely free of this
kind of mean-spirited nonsense, so it really took me by surprise.

------
sgillen
I mean sure Pony, but as a programmer this result would surprise me quite a
lot, which I tend to view as a bad thing.

[https://en.wikipedia.org/wiki/Principle_of_least_astonishmen...](https://en.wikipedia.org/wiki/Principle_of_least_astonishment)

However:

> One of developers of Pony reached out to me. They’re planning on writing a
> more in-depth explanation of why Pony chose 1/0 == 0, which I will linked
> when available. As I understand it, it’s because Pony forces you to handle
> all partial functions. Defining 1/0 is a “lesser evil” consequence of that.

I am looking forward to this write up.

~~~
ggggtez
Based on the tweet, I don't expect it to be very enlightening. Since
programmers write programs to solve real problems, and real problems define
1/0=undefined... then this is only going to mask bugs in those programs.

~~~
mcguire
Technically, some real problems define 1/0 as illegal.

But see renormalization.
[https://en.wikipedia.org/wiki/Renormalization?wprov=sfla1](https://en.wikipedia.org/wiki/Renormalization?wprov=sfla1)

------
emileokada
It's quite staggering how many people have posted on this thread without
reading the article. Nearly all the objections people have raised are directly
addressed in the post.

For those who still object to the argument, would you object to me defining
the piecewise function f:R->R defined to be 1/x for x =/= 0 and 0 for when
x=0?

~~~
antidesitter
_Nearly all the objections people have raised are directly addressed in the
post._

Are they? I see nothing in the article about the negative consequences of
surprising users with silent failure, for example. Or the fact that it makes
little sense in real-world scenarios.

 _would you object to me defining the piecewise function f:R- >R defined to be
1/x for x =/= 0 and 0 for when x=0?_

What do you mean by objecting to you defining a function?

~~~
Zalastax
The post is not about whether this is a good choice for its users; the post is
about whether there are nathematical objections to it. The author even writes
that they don't agree with the _engineering decision_ to define it like that,
but they can't object with an appeal to mathematics. It lists three valid
choices for handling division by zero and Pony picked one of them. My personal
favorite is to shrink the domain but that's not supported in most languages
and those that support it are often not meant for number crunching.

------
jdietrich
What proportion of the time will a programmer _intend_ and _expect_ 1/0 = 0?

What proportion of the time will a divide-by-zero operation be a symptom of a
bug, where evaluating 1/0 as any valid number will make it harder to identify
that bug?

There might be a mathematical justification for 1/0 = 0, but the computer
science justification seems tenuous at best. The overwhelming majority of the
time, I want divide-by-zero to throw an exception or evaluate to NaN. I'd far
rather deal with the edge case of _intentionally_ dividing by zero, rather
than the not-at-all-uncommon case of unintentionally dividing by zero and
getting unexpected behaviour as a result.

~~~
derefr
We’re talking here about integer math. Integer math on CPUs is usually fast at
the expense of having coherent semantics. It isn’t even really “integer” math
in any mathematical sense. It’s just “the fastest math that the CPU is capable
of doing, which happens to look a lot like integer math most of the time.”

If you’re dividing floats, you will get NaN or Infinity as expected. Just like
how, if you overfloat a float, you’ll get Infinity. Floating-point has well-
defined semantics, which CPUs are required to adhere to, and languages just
expose.

If you divide “CPU integers” by (CPU integer) 0, the result is undefined. Just
like how, if you overflow a “CPU integer”, the result is undefined. There is
no standard semantics being adhered to. There is no equivalent of IEEE754 for
CPU integers. There is only convention, and convention has no universal answer
at these edge-cases. Thus, a language is free to do whatever it wants in
response to either. There are no formal semantics to expose.

Usually, a language that calls itself “safe” will choose to make CPU integers
behave a lot like real integers, by generating checks and throwing exceptions
for the edge cases.

And usually, a language that calls itself “low-level” will just expose
whatever semantics the CPU integers of its host platform already possess. In
the case where there’s still an impedance mismatch (i.e. in the case of
division by CPU-integer-0 where you don’t actually get any output into a
result register), the language has to make something up. To “go with the flow”
of how CPU integers work, probably it should be something fast.

Thus, 1/0=0 _kinda sorta_ makes sense. It is an operation on the field of “CPU
integers” that vaguely “fits in” with the existing ones. No mathematical
relevance, but just fine from the perspective of someone e.g. seeking to
create a higher-level abstract machine targeting the Pony compiler, where
you’d still just insert a divisor check before doing the division op if you
wanted the result to make any sense.

~~~
cryptonector
Thanks for this explanation.

------
calhoun137
I very strongly object to this convention, as both a programmer and a
mathematician.

A basic theorem is that for any field we must have that a/b = c/d if, and only
if, ad = bc. See theorem 2 in this classic text here for a proof[1]

So if 1/0 = 0, then we also have 1/0 = 0/1, which implies 1 x 1 = 0 x 0 which
is a contradiction. But then we also have 1/0 = 0/x for any x, hence we also
have shown x=0 for any x, which is an infinite number of contradictions. Is
this a problem which is addressed in the post that I missed?

By the way, I have spent more time than it's polite to discuss in public
studying the topic of dividing by zero, and also what 0/0 means. If you are
also interested in this topic, the best youtube video is by Mathologer and I
highly recommend it to everyone. See here [2]

[1]
[https://books.google.com/books?id=3ApEDwAAQBAJ&lpg=PP1&pg=PA...](https://books.google.com/books?id=3ApEDwAAQBAJ&lpg=PP1&pg=PA4#v=onepage&q&f=false)

[2]
[https://www.youtube.com/watch?v=oc0M1o8tuPo](https://www.youtube.com/watch?v=oc0M1o8tuPo)

------
mreome
So... if I do:

    
    
       x = a/b + c/d + e/(f*g/h)
    

I need to check:

    
    
       if(b == 0 || d == 0 || f == 0 || g == 0)
    

rather then:

    
    
       if(isFinite(x)) 
    

Or whatever function/equality check is appropriate, or a try/catch if it
throws an exception.

I have to say that using a single check on the result seems significantly less
prone to bugs then having to check all the values that could produce an
invalid result.

~~~
cryptonector
Without NaN you don't get to see that the computation "went wrong". But that's
not necessarily a problem, and only if it is must you check whether those
inputs are zero.

Still, I agree that a NaN value(s) is(are) preferable for this reason.

~~~
mreome
Of course, there will be cases where you need to check some of the initial
values regardless, but often you just care if the result is valid. From a
defensive programming stand-point, if you don't expect any of those values to
be zero, you just check for NaN at the end rather then carefully reviewing
your calculations for which values you have to check.

I would REALLY hate having to write a geometry library without NaN values.
Both because of error checking, and the fact that NAN/INF is often the
'correct' answer when it's the result of a calculation.

------
bluecalm
This is very bad for numerical code. When you divide by almost zero you get a
big number. If it becomes a zero it should be even bigger number. Having 1/0 =
+inf is a perfect solution. Setting it to 0 breaks continuity and isn't useful
at all.

One of those proposals which can only be made when you don't take time to
understand and appreciate use cases the current solution was created for.

~~~
dlubarov
> Having 1/0 = +inf is a perfect solution.

It makes sense if we have signed zeros; then +0 represents an infinitesimal
positive value. IEEE 754 has signed zeros, though the signs may sometimes not
match programmers' expectations, e.g. 1 - 1e-50 - 1 == +0.

Maybe 1/+0 == +inf is reasonable, but would you agree that there's no
reasonable answer for 0/0? So IMO, reasonable languages must define division
as a partial function, or a function that can throw an error (or return NaN,
Nothing, etc).

And if division is a partial function anyway, it seems best to not allow
division by zero at all, since even 1/+0 == +inf can have unexpected
consequences.

------
kazinator
> Lawrence Paulson:

> > _These things are conventions, exactly the same as announcing that x^-n =
> 1 /x^n and that x^0 = 0._

Say what? x^0 is 1, and not by convention, other than in the 0^0 = 1 case.

~~~
nextstep
I was thrown by that too, maybe it was a typo?

------
lisael
FWIW Pypy used to share this behaviour. It was clearly a bug, as it doesn't
follow CPython convention.

It's around since 2013 and was found in a unit test coverage improvement
effort in Feb. 2018.

Given that pypy is mostly used for hard-core math and scientific computations,
how the hell this bug wasn't found earlier by a user ?

My bet is that ZeroDivisionErrors are very rare. Do you even remember a
ZeroDivisionError in production code ? I don't.

1/0 is my dirty little trick to add a breakpoint when I'm too lazy to launch a
debuger. Why does this work? Here again, because nobody never catch
ZeroDivisionErrors, because they don't happen.

So, what a fuss for such a tiny convention. Granted, it breaks the math
correctness, as do ±Infinity. CPU integer math is broken anyway. In what world
does 2^31 - 1 + 1 == -2^31 ?

I took a fairly large, used and old repository, Django and I search for
ZeroDivisionError:

[https://github.com/django/django/search?q=ZeroDivisionError&...](https://github.com/django/django/search?q=ZeroDivisionError&unscoped_q=ZeroDivisionError)

guess what:

\- 4 occurrences in the tests

\- 3 occurences in the issues

\- last, but not least 1 occurrence in the code:

    
    
       except ZeroDivisionError:
           result = '0'

------
JackFr
Oh sure, there are infinite numbers of matrices without inverses and no one
cares.

But you try to slide one little real number without an inverse by and everyone
freaks out.

------
j2kun
> We’ve now established that if we choose some constant C, then defining
> division such that x/0 = C does not lead to any inconsistencies.

There is no proof in this post that 1/0 = 0 maintains consistency. Rather, it
contains refutations of one or two arguments that claim inconsistency, along
with appeals to authority.

~~~
hyperpape
You're right. It really would've been nice for the author to offer a direct
proof.

However, while I'm a bit rusty, I think it basically has to be true. For there
to be an inconsistency, 1/0 = 0 must either

a) imply the negation of some previous theorem of arithmetic or

b) imply that 1/0 = x, for x != 0.

I think a) can only be true by way of b), since no existing theorem of
arithmetic involves the expression y/0 for any y. I confess, I don't know the
right way to prove that b cannot be a consequence, but it doesn't look like
one.

Edit: I think it's just trivial to take a model of the existing axioms, then
add n/0 = 0 to the division relation.

~~~
j2kun
You have to add extra "except when"s to every theorem involving division.
E.g.:

(a+b)/c = a/c + b/c

(in particular, for C != 1, as the author claimed it would work not just for 0
for for any real number)

Now to say this is true you have to say "unless c = 0", whereas before that
was automatic from the definition of division.

~~~
hyperpape
The same theorem

forall c != 0, (a+b)/c = a/c + b/c

is true before and after.

It may be helpful to observe that while using the same symbol '/' in both
cases is confusing, mathematical theorems are not about symbols, but about
particular mathematical objects. The old theorem is about the division
relation defined for real numbers != 0, the new one is a relation defined for
all real numbers, that just happens to coincide.

~~~
j2kun
That is exactly my point. Now you have to disambiguate a poorly-chosen symbol.

The theorem doesn't need the stipulation that c != 0 since you have already
excluded c from the domain.

------
whatshisface
The explanation in the article basically boils down to the following:

let a/b mean, in my programming language's syntax, = { a divided by b when b
is not zero, or 0 otherwise.

Yeah, it's not "mathematically invalid," but it punches a hole in the fidelity
between numerical methods and the math that they approximate.

~~~
IAmTheTucan
I knew that but my friend didn't. So thank you for explaining that for my
friend.

------
narrator
This is "Worse is Better[1]" engineering at its most infamous. In order to
make the interface consistent and simple you take the exceptional case and
just make it work the same as all the other cases. It goes with the "Worse is
better" credo that "it is slightly better to be simple than to be correct".
Also "it is better to drop those parts of the design that deal with less
common circumstances than to introduce either complexity or inconsistency in
the implementation". So throwing an exception on division by zero or returning
some complex thing like NaN is too much complexity, so we just return 0.

[1]
[https://en.wikipedia.org/wiki/Worse_is_better](https://en.wikipedia.org/wiki/Worse_is_better)

------
todd8
Let f(x) = 1/x, then (from a mathematician’s perspective) the limit of f(x) as
x->0 doesn’t converge and is representeted as being infinite, definitely not
zero.

As the denominator gets smaller, the result is bigger and bigger and bigger.
The closer the denominator gets to zero the larger the result. Why would we
want to pick an answer that is small when instead it should be larger than any
number?

One might argue that 1/0 should be MAXINT or IEEE 754 plus infinity due to the
limitations of our hardware, but I’ve never wanted 1/0 to result in zero in
any program I’ve ever written.

I would prefer that it be treated as an error or possibly some reserved value
that behaves like INF while still being an integer in the programming
language.

~~~
ummonk
Well, you have an ambiguity as to whether it should be +INF or -INF, depending
on which side you take the limit from. Arguably, 0 is more reasonably because
it preserves symmetry. Of course, it would be far more reasonable to define
this as an exception, because you shouldn't be able to do division by 0.

------
Ceezy
First the difinition of given of a field is wrong
[https://en.wikipedia.org/wiki/Field_(mathematics)](https://en.wikipedia.org/wiki/Field_\(mathematics\))
. But why not? the author might not know but 1/0 is by definition the inverse
of 0 and that s why 1 * (1/0) = 1. What he do is extanding the definition of
the division FUNCTION. And you can always do that. But by doing that you lose
most of algerbaic and arithmetical propreties for numbers. But worst! There
exists 1/ 0 = infinity, but also infinity * 0 = 0(in probability). So please
stop creating fake controversies about stuff that really doesn t need ANY
DEBATES.

------
ggggtez
> But is Pony doing something unsound? Absolutely not. It is totally fine to
> define 1/0 = 0. Nothing breaks

a=x/N

b=y/N

If a==b, then x==y

No longer true, with this change. Essentially a variety of mathematical
properties of numbers in the Real space don't hold when you allow division by
0.

~~~
ajanuary
“Nothing breaks” in that it isn’t unsound, in that you can’t use it to prove a
falsehood. Not that you can’t use the nice little shortcuts you’re used to.

In practical terms, that _does_ have an impact, because people might use those
shortcuts without realising the system they’re operating under doesn’t allow
it.

But you picked the wrong quote to make that point under.

~~~
lisael
To elaborate on the 'nice little shortcut' you mentioned, here it is:

If a==b _and N≠0_ , then x==y

EDIT: Formatting

~~~
ummonk
No, that is not necessary.

"Given an x, y, and N such that x/N == y/N, it is true that x == y".

There is no need to say N != 0 under the ordinary definition of division.

------
abakker
I am not really a programmer or mathematician, so take this for what it is,
but to me, the statement makes linguistic sense, if you read it out like a
first grader.

If I divide one thing into zero groups, how many items do I have in each
group? Zero. Edited per comment below.

If I were really pedantic, I'd say that in the above, it's almost like the
input "1" is not being divided, but grouped.

The funny thing then, is that if I am grouping instead of "dividing", then if
I enter 1 modulo 0, I'd expect to get 1. i.e. the modulo zero should be an
identity function: 1%0 = 1, c%0 = c.

~~~
rubatuga
I think you mean if I divide one thing into zero groups, how many items do I
have in each group

~~~
abakker
Edited, thanks!

------
blablabla123
I must admit I prefer 1/0 not to be 0 in the "Common Algebra". But that might
be because I come more from an Natural Science/Engineering background where
continuity is something that is expected virtually everywhere. Not even
Theoretical Physics text books mention that continuity of functions is
required as it is so ubiquitous. 1/0000000.1=10000000,
1/0.00000001=100000000.0, ..., 1/0=0 would break that. In fact we have even
harder requirements usually we want everything at least twice
differentiable...

However, nobody stops people from defining their own Algebras or Fields on
languages that support it. On C++ this should be a no-brainer, if the
sentiments of the article is true that consistency is no problems. Being a
"man of industry" myself, 1/0 throwing or at least becoming infinity doesn't
seem a problem to me. Similar to not using gotos or so.

FWIW, JavaScript an underrated language when it comes to weird corner-cases
does the right thing. It doesn't throw an error, instead the result becomes
Infinity. When I multiply it with a finite number it stays Infinity. When I
multiply it with 0 it becomes NaN which is totally sound because in a real-
world application one could come to these numbers because of limitations of
the storage. 0.00000......1 becomes 0 thus the real result of 1/0 x 0 in that
case can indeed be literally _everything_. The beautiful thing about
JavaScript is how it continues to handle this, when I say 1 < NaN or 1 > NaN
it stays false. So the algorithms are likely to fail much more graceful than
in other languages.

~~~
lucian1900
JavaScript’s behaviour is just how floats work. They are the same in all
languages. There is storage reserved as part of their representation to encode
infinity and NaN.

The issue here is hardware integers, which have no signalling bits beyond
possibly sign.

~~~
blablabla123
Sure, JavaScript uses floats for everything. But the article seems to be
actually mostly about real numbers: "The real numbers, along with our
conventional notion of addition and multiplication, form a field." (Ignoring
the fact that there are finite fields that are properly closed under all
operations)

------
red_admiral
> These things are conventions, exactly the same as announcing that x^-n =
> 1/x^n and that x^0 = 0.

The convention that x^0 = 1 (including 0^0 = 1) is genuinely useful because it
removes a case distinction from lots of combinatorial formulas. Hence this:
[http://tinyurl.com/zeropowerzero](http://tinyurl.com/zeropowerzero)

x^0 = 0 seems to me to be - I won't say "wrong" because you're free to define
things the way you like - in general less useful than x^0 = 1.

For similar reasons, (0 * log 0) = 0 makes sense when computing entropies and
stuff in certain machine learning applications. This one can also be justified
as the limit of x * log(x) as x -> 0 is 0, but I've seen at least one person
just trying to define "log 0 = 0" which I consider less elegant; in the kind
of application where this convention is useful, you'll rarely if ever see a
log 0 that's not multiplied by a plain 0.

Where it gets really weird is when you do KL divergence and can end up with 0
* log (0/0), but again you can save a case distinction by just declaring this
to be 0. The elegant way to do this is to define d(p, q) = p * log(p/q) when
p, q != 0 and 0 otherwise. In this particular application, just going with 1/0
= 0 seems to work fine in practice as in a term q * log(q/0) you can rewrite
the whole thing by flipping the sign to get 0 * log(0/q) in that term, which
we have already declared to be 0 (whether or not q is 0 itself).

In this case it's not a bug in the code, it's being able to handle probability
distributions with mass 0 on some points at the level of arithmetic rather
than as a special case in the formula.

------
j2kun
You lose simple properties of division, such as (a + b)/c = a/c + b/c.

If you set 1/0 = 1 (as the author claimed causes no inconsistency), then (2 +
1)/0 = 2/0 + 1/0 is false

If you come to rely on division by zero behaving a certain way (as happens to
all features/bugs of any language), then suddenly silly decisions about how to
implement a formula can cause wildly different behavior. Good luck
refactoring!

~~~
lisael
(a + b)/c = a/c + b/c _for c ≠ 0_. Otherwise it has no meaning.

Therefore (2 + 1)/0 = 2/0 + 1/0 is not even false, it just means nothing.

BTW, you didn't mention Infinity explicitly, but it would lead to the same
inconsistency, if you think about it:

(2 - 1)/0 = 2/0 - 1/0

:)

~~~
j2kun
If you define a/0 to be a value, then you can ask whether (2 + 1)/0 = 2/0 +
1/0\. This is not meaningless since both sides are defined. If you define a/0
= 2, then the equation is false.

Using "infinity" (which is not how it's actually done in math) requires you to
rule out the possibility of operations like infinity - infinity.

------
BillBohan
I had considered this as a possibility following much the same train of
thought expressed by abakker but because it diverges from most common practice
(and from mathematics) and because I was unsure whether anyone would actually
want it, I had not really considered using it.

While reading the article and the comments I realized that it will work
perfectly in my NISC processor [1]. I just need to update my specification.

To extend the simple first specification to include multiply is very simple. I
just need to have a MUL register which, when written, multiplies the written
value by the value in the accumulator with the low part of the result being
left in the ACC and the high part in the MUL register.

Extending to include integer divide is a little more complicated. I will have
to add a DIV register and a DIVEX register. Writing to DIV will divide the
value in the ACC by the value written leaving the result in the ACC and the
remainder in the DIV register. DIVEX will contain the address of the routine
to call when division by zero is attempted which means that DIVEX must be
loaded before division is used. If I specify that DIVEX is initialized to zero
by the hardware and that DIVEX==0 means that divide by zero leaves zero in the
ACC and the remainder (former contents of ACC) is left in the DIV register
then 1/0 = 0 will be the default behavior with the ability to change that
behavior simply by writing the address of the divide exception handler to the
DIVEX register.

I leave it as an exercise for the reader to determine how to deal with this in
high level languages. I can fully support it in machine code and assembly
language.

[1] [https://github.com/BillBohan/NISC](https://github.com/BillBohan/NISC)

------
makecheck
I’m not sure if a general system should deviate from established definitions
but in specific _programs_ I certainly bend the rules.

For instance, I made a game, and I might accidentally end up with a value that
won’t modulus correctly due to zero denominator. In that app, _mathematical
accuracy for this single outlier does me no good at all_ because it manifests
as “might crash randomly” when I want “doesn’t crash, period”. I therefore
wrote a “safe modulus” routine that essentially guards against zero and makes
a command decision to return a value. The added robustness against crashes is
preferable, since I may not know if I have found every stupid case of the math
accidentally working out to exactly zero.

In fact, more generally, exact zeroes mask lots of bugs. They are often
default initial values, meaning you might not notice something working
accidentally. Sometimes I use a really tiny float as my “meant to be zero” to
distinguish, e.g. 0.0001 means “item was supposed to appear at coordinate 0”,
that way anything that accidentally ended up at 0 is easier to detect.

------
ummonk
The standard definition of r = p/q is the number that solves the equation rq =
p. This version of "division" does not satisfy that definition, and is
therefore not actual division. Call it division* or something.

Edit: it seems that Pony is only doing this for integer "division", which
isn't regular division anyway, and the standard rules don't apply.

------
veritas718
I remember that 1/n is saying 1 with respect to n increments. 1/4 is 1 out of
4 buckets (of 1 integer). If you have 1/no buckets, it is an amount, but it is
impossible to know how much. It's measuring a caterpillar without a unit of
measure. "He's 7" "Ok, Im sure he is, but 7 what?" 1/0 may approach 0, but it
is not 0.

------
ezequiel-garzon
But what does it give you? I may not like PHP's definition of "5uper" \+ 3 as
8, but at least I can see an advantage to it, a use for it. What would you do
with that zero quotient, any examples? And I mean examples where you haven't
checked the value of the divisor (otherwise what's the point). I appreciate
spooneybarger's input as a core developer of Pony, because he lets us know
this was a difficult decision, and frames the definition squarely in the
context of the language.

On the other hand, the author of the article seems to push for a general,
mathematical definition of 1/0 as 0. First of all, good luck with that, as
there is no standards-issuing body in mathematics. And whether the author
likes it or manages to overturn a very long tradition, division _is_ defined
_when we grow up_ as multiplying by the multiplicative inverse, with some
occasional notes like "Division by zero is undefined for the real numbers and
most other contexts [1] or "In general, division by zero is not defined [2],
pointing to settings where clearly you won't find consensus.

I refer to when we grow up because we should not forget the intuitive
definition Wikipedia gives first and, I guess understandably, MathWorld gives
last: "separating an object into two or more parts". As we know, this
restriction of _two parts_ can (more and then less) intuitively be loosened to
one, negative numbers, rational numbers, real numbers, etc., but only
arbitrarily for zero. But then again, even if we unanimously agreed on one
value, what does it give you?

[1]
[https://en.wikipedia.org/wiki/Division_(mathematics)](https://en.wikipedia.org/wiki/Division_\(mathematics\))

[2]
[http://mathworld.wolfram.com/Division.html](http://mathworld.wolfram.com/Division.html)

------
fmap
Well, it's a design choice that you can make for rational numbers and the
restricted rationals with error values that we typically use in computer
arithmetic. There's nothing wrong with it and as the article points out, even
most proof assistants use this definition for rational division.

For real numbers though, division by zero will always diverge or be undefined,
no matter how you represent them. All computations on real numbers are
continuous and there is no continuous extension of division which includes 0
in the domain of the denominator.

One can get around this by switching to projective reals (essentially reals
extended with a new element that's both +infinity and -infinity). This is no
longer totally ordered and has some other problems, but it's actually a great
choice for a lot of numerical computations. Yet, I've never seen something
like this implemented in hardware, aside from John Gustafson's unum concept.

------
krylon
Once a mathematician explained to me in mind-numbing detail why dividing by
zero is impossible, so I understand why this is gross better than I ever
wanted to.

 _But_ having said that, I do not remember when I last saw a Divide-by-Zero-
error in the wild. In practical terms, this is the last kind of bug I worry
about.

------
westurner
1/0 = 1(±∞)

[https://twitter.com/westurner/status/960508624849244160](https://twitter.com/westurner/status/960508624849244160)

> _How many times does zero go into any number? Infinity._ [...]

> _How many times does zero go into zero? infinity^2?_

~~~
earenndil
Zero goes into zero x times, for any real x. Infinity isn't real, therefore
neither is infinity^2 so no.

~~~
westurner
Extrapolate.

What value does 1/x approach?

What about 2/x?

And then, what about ∞/x? What value would we expect that to approach? ∞(±∞)

~~~
earenndil
It doesn't approach anything, it's unbounded.

------
daniel-cussen
I've used this workaround in genetic algorithms, as has John Koza, the pioneer
of the field.

The idea behind this is you're never going to get the computer to program
itself with exceptions, so better not to let it produce code it will not be
able to execute fully without human intervention.

------
mayoff
In some languages, you could define a new division operator that returns an
Optional/Option/Maybe result, and then use a nil-coalescing operator to choose
what you want in case of division-by-zero. In Swift:

    
    
        infix operator /? : MultiplicationPrecedence
        extension FloatingPoint {
            static func /? (lhs: Self, rhs: Self) -> Self? {
                return rhs == 0 ? nil : lhs / rhs
            }
        }
        extension BinaryInteger {
            static func /? (lhs: Self, rhs: Self) -> Self? {
                return rhs == 0 ? nil : lhs / rhs
            }
        }
    
        10 /? 2 ?? 0  // -> 5
        10 /? 0 ?? 0  // -> 0
        10 /? 0 ?? 10 // -> 10

~~~
spooneybarger
You can't define your own in Pony but,

/?, *?, +? and -? are coming to Pony. We call them "safe math operators" and
will error on integer overflow, underflow, and division by zero.

------
bcheung
I consider it infinity because the limit as the denominator goes to 0 is
infinity.

I see this with investments that have infinity ROI. If you get into an
investment using only other people's money (OPM) and you make a profit then
you have made x / 0\. Saying I made an infinity return makes more logical
sense than I made 0 return.

There's a saying about the difference between a mathematician and an engineer.
If there is a $100 bill on a table and each step you take must be half the
remaining distance or less the mathematician will never get there, but the
engineer will get there no problem.

It's a non-sensical debate IMO but from the investing scenario that I
described above, for all practical purposes, it makes more sense to consider
it infinity.

~~~
aapeli
> I consider it infinity because the limit as the denominator goes to 0 is
> infinity.

Note that this only works if the denominator approaches 0 from a positive
side. Otherwise it's 0. This is the idea behind the extended real numbers.

------
justinfrankel
FWIW the EEL2 language (part of
[https://www.cockos.com/wdl/](https://www.cockos.com/wdl/) and what powers
REAPER's JSFX audio, video processors, etc) also makes this design decision...

------
bjd2385
To be honest, this is the kind of post I'd write after a few beers when I'm
not giving a shit and I think people have the right idea about something a lot
of people would find controversial. Great post! You've made a real
contribution here.

------
blablablerg
If something is undefined in math, it doesn't mean define it with whatever
value you want: it means undefined because you can't define it.

The function sqrt(x) is undefined for negative x in the real number system. Is
it therefore zero? No. Just because a value is not in a domain doesn't mean
just pick one.

Most math textbooks I know and Wikipedia define division as the inverse of
multiplication. You are saying that there is a distinction, the inverse of
multiplication is not the same as division: you can write 1/0, but that is not
the same as 1 * 0⁻.

This is unconventional to say the least, and the only argument you give to
make this destinction is your desire to define 1/0 as 0.

------
joppy
I don’t really understand the main argument given in the article; since zero
has no multiplicative inverse, you can’t prove anything involving a division
by zero. (So why talk about field axioms?)

However, to extend an operation usefully to a larger set of numbers, we can
isolate some properties that we want to keep, for example:

1\. Division is linear in the first argument: (ab + c)/x = a(b/x) + c/x, for
all a,b,c,x.

2\. If x has a multiplicative inverse, then x * (1/x) = 1.

3\. Taking reciprocals twice gets back to the original number: 1/(1/x) = x for
all x.

The choice 1/x = 0 is consistent with all the above, and so probably still
“useful”. What properties do you want out of a division function?

------
alkonaut
Any division either works and returns a result, or doesn't work and doesn't
return a result. This is similar to any other function that _maybe_ returns a
result (returns an Option<T>/Maybe<T> or even Result<T, E>).

Perhaps it's not a good design to have division as an operator a programming
language? Just like

Maybe<int> i = ParseInt("foo")

one should also do this for division:

Maybe<int> q = Div(n, d)

Is there any language that does this (returns an option for default division?)

Obviously, this is also the case for ALL other operations on finite number
types because of overflow. But overflow is MUCH rarer than division by zero
issues, at least in my experience.

~~~
spooneybarger
That's interesting. In my career, I've rarely encounted division by zero. I've
encountered over and underflow considerably more. Different experiences,
different points of view.

------
mirimir
As near as I can tell, he's just redefining what division means when the
divisor is zero. That is, creating a special case. And yes, I get that it's a
useful hack in programming.

So anyway, IANAM. What I learned was that 1/0 is infinity. And in software,
that generally means a divide-by-zero error. But I also learned the utility of
making approximations and exploring behavior at limits. And 1/x obviously
increases exponentially as x approaches zero.

So how, then, can 1/x all of a sudden be zero when x is zero? It makes no
sense to me. Call it undefined if you like. But it's obviously not zero.

~~~
kenbellows
1/x as x -> 0 is a famously tricky expression because your statement that it
"obviously increases exponentially as x approaches zero" is only true half the
time, because it's only true if you approach zero from the positive side, with
x being set to smaller and smaller positive values. If, on the other hand, you
set x to negative values of smaller and smaller size, 1/x actually _decreases_
toward -Infinity. This is one of the several reasons that 1/x is typically
considered undefined for the Reals.

~~~
mirimir
Damn, so last night I was thinking about how 1/x approaches ∞ for positive x,
and -∞ for negative x. And it struck me that perhaps beyond both ∞ and -∞ is
0, so 1/x might actually equal 0 when x is 0. Rather like closed "liner" paths
in closed universes. But again, IANAM ;)

------
ian1321
I know nothing about pony, but if it does have an optional type, this would be
a much better choice. You lose information by returning 0. Returning "none"
would keep the information that you tried to divide by 0. Of course, this
means all division would return an optional instead of a value. This is the
cost of safe, robust programming.

<rant> I see a lot of software engineers trying to get rid of the cost of
writing robust programs. It's not possible. Stop trying. You are either safe,
or you are not. You either handle all cases, or you don't. </rant>

------
gwbas1c
This is a case of poor abstraction. Many commenters in this thread explain
why, in their application, 0 is a good fallback for division by zero.

But, falling back to 0 is not the correct error handling result for all
situations. In other situations, an error is the correct result. The language
designers should include proper division, and this style of division should be
labeled a "safe" division; or, a division that throws an error should be
labeled an "unsafe" division.

I have serious doubts about a language if it chooses one-size-fits-all error
handling like this.

------
perl4ever
This item reminded me of how I've owned a couple different German cars with a
fuel consumption meter that showed minimum consumption (or maximum mpg) when
the car was idling. It seems like they must indeed have defined (fuel used ÷
distance traveled) as zero when the distance is zero. Which is annoying and
grossly wrong in my opinion. For some reason, Japanese cars seem to do it
correctly.

It may be true that 1/0=0 can be part of a reasonably consistent system, but
that doesn't mean it's a good one. Can we define 1/0 as ∞?

~~~
joppy
I don’t think 1/0 = infinity is a good choice either, since -1/0 = 1/(-1 * 0)
= 1/0, so we would have infinity being equal to negative infinity, which is
assumedly not a practical choice. 1/0 = 0 is actually more symmetric in this
regard.

------
espadrine
While I fully agree, I'd like to point out that reducing specifically to 0/0 =
0 is more generally useful (ie. maintains intuition) than x/0 = 0, which
breaks intuition.

Given a/b = c, your intuition of finding c is to get a number such that c×b =
a.

c×0 = 0 has an infinite number of solutions, 0 being a particularly practical
one.

c×0 = 1 (and more generally a≠0) has no solution, especially in the reduced
explanation of multiplication as taking integer multiples of a value.

(Also note that having 0/0 = 0 maintains symmetry and continuity of the
function y = 0/x.)

~~~
abakus
But this is not for man of industry!

~~~
espadrine
It is stunningly practical.

------
mortdeus
there is a pretty good episode on numberphile that explains why dividing by
zero is undefined.

Basically the reason why 1/0 = 0 is wrong is the fact that you cant reproduce
1 by taking the answer 0 and multiplying it by 0 to get the number being
divided. Which goes on to break a bunch of other fundamental rules of
mathematics.

That is to say, if you took 6 / 2 = 3 you can reverse the division by doing 3
* 2 = 6.

However if you have 6 / 0 = 0 and you were to try and reverse it then you
would have 0 * 0 != 6. Then you have bizarre circumstance where everything
decided by zero logically equals the same thing. Where (2 + 2) / 0 all of a
sudden equals (Einsteins laws of gravity) / 0\. And there is no logical way to
really explain what that is supposed to mean.

Also if you try to use limits to find a solution of f(x) = 1/x where x is
defined as the limit of 1 and -1 as it approaches 0 from both sides. You end
up with the answer that is even more confusing when you try to graph it.

That is x = +inf and -inf. Which on a graph is represented as two curves where
the limit as 1 -> 0 from the positive side of the x axis curves up along the y
axis to infinity without intersecting where x=0. And from the negative side
where we approach 0 from -1 we end up with a curve that moves down the -y axis
without intersecting at 0.

So frankly, n / 0 = 0 just doesn't make sense because just trying to approach
it from both sides suggests that the closer you try to move to zero from both
sides the further apart the answer moves away from converging together at the
origin. Which would be expected if n / 0 = 0 was actually true.

------
tobiasSoftware
I'm writing a software language that has 1/0 = 0 as well. In my case, I am
experimenting with several ideas, two of which are no runtime errors and no
exceptions, so everything is either a logic error (aided by multiple return
values) or a compiler error. It works fine in normal scenarios, but dividing
by zero can't be caught at compile time, and operators can only return a
single value, so I had to return something.

------
snissn
It is the average of 1/0+ and 1/0-

So at least that's something

~~~
JadeNB
> So at least that's something

It's also nothing. :-)

------
arithma
Sometimes I have a feeling that I should be avoiding division in all cases to
begin with, but then, there are cases where it seems all too indispensable.
Especially when a value is a measure with an ignored error, division close to
zero is almost meaningless. Is it a realistic goal to try and avoid division
in the first place? I don't remember my numerical computing course well enough

------
bogomipz
I have lower level question about how Pony implements this behavior:

When a CPU is asked to divide by zero it generates an exception. This
exception would cause the OS to jump to the interrupt handler in the IDT for
divide by zero exceptions. This handler generally results in the OS
terminating the process. Does the Pony runtime register its own signal handler
with the OS for a divide by zero exception?

------
dubhrosa
An alternative to multiplicative inverse is to think of division x/y as
allocating an amount x to y recipients; this is a very common operation in
finance, eg allocating x shares to y accounts, or if you prefer, splitting a
bill x among y diners. In this interpretation, you can't allocate anything to
0 recipients, so its reasonable and convenient to set 1/0 = 0

------
ushi
Ruby defines division by zero for Floats

    
    
      1.0 / 0
      => Float::INFINITY
    

and

    
    
      0 * Float::INFINITY
      => Float::NAN
    

I think infinity is a more intuitive result, but most of the time i get this
as a user i would rather see 0 (bought books per month: Infinity). As a
programmer i like to get an error, because i forgot to handle an edge case...

~~~
scarejunba
That's IEEE 754
[https://en.wikipedia.org/wiki/IEEE_754#Exception_handling](https://en.wikipedia.org/wiki/IEEE_754#Exception_handling)

------
sonnyblarney
1/0=0 is basically crack for the HN crowed, I knew it as soon as I saw it,
just 5 little characters would drive people into the mouth of madness.

It's like WWE Raw Smackdown, Hulk Hogan vs. The Rock and everyone has to take
a side.

And it's literally Friday night.

Sorry we're not supposed to comment like this buy y'all (I suppose 'we') are a
really funny bunch sometimes.

------
cuspycode
The article uses two example theorems to justify this: a * (b/c) = b * (a/c),
which can be extended to cover the c=0 case, and a/a = 1, which can be
extended to cover the a=0 case. I can see how this can be useful in some
situations, but it's not natural in the same way as e.g. analytical
continuations of complex functions are.

------
skybrian
In case you're wondering, Elm has a strict "no runtime errors" rule, but
avoids this by not having integers.

Another interesting example is array access. What should a[len(a)+1] be if
your language doesn't have runtime errors?

Elm returns a Maybe type. However, this would be very awkward if you're
actually doing a lot of calculations using arrays.

[Edit: Pony is different.]

~~~
lisael
Pony does have exceptions, and indexing an array does raise if the index is
out of bound. It doen't have runtime errors because all exception must be
handled somewhere in the call stack, the sooner, the better.

Because of this rule, defining / as a partial function forces the user to
fence every single division in a try clause.

Using boxed integer as Elm does is not an option as Pony targets high-speed
computing, not browser rendering. Different fields, different trade-offs.

Defensive users can well define `div(I32, I32): I32?` that throws an error and
use it instead of `/`.

As repeated in this thread, 1/0 is undefined because nonsensical. So, it's OK
to have any sane, consistent and well documented behaviour. At least with
Pony, the user can choose speed and convenience when they're sure there is no
possible 0 at this place. Well, TBH, I think it's always the case. Because
there is no such thing as a division by zero, you're algorithm is simply wrong
and unsound if it ends up dividing by 0, and that's where this case differs
from integer overflow

Note: in Pony literature, "partial" means "can throw an error". "partial" as
in "doesn't apply to the whole domain of the arguments types"

------
sgt101
Julia gives "Inf" and Inf+Inf =Inf and 1/Inf = 0.0

I prefer this because if you have a function converging on 0 then you will see
growth towards Inf - then Inf - rather than growth followed by a cliff; which
could then propagate into all your other calculations and move you from the
very small to the very large in an instant.

------
kelvin0
Sometimes I wonder how much actual energy is expanded by humanity in such
'debates' (electricity, coal, nuclear..). I'm just that kind of person that
likes to put thing into perspective. I'm certainly as 'guilty' as the next
person in engaging in such trifle matters :-)

------
perlgeek
This triggered an immediate "that is wrong!" response from me, which I had to
suppress to actually read the argument.

From this definition, I'd guess that pony isn't optimized for numerical code
and floating point operations, because there it tends to make less sense.

~~~
spooneybarger
Please note 1/0 = 0 in pony is only on integer math.

1.0 / 0.0 = infinity per the standard.

1/0 = undefined behavior and is left to language implementers to decide how to
handle.

------
PopeDotNinja
Meanwhile, in Python v3.7.0...

    
    
          >>> 1 / 0
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
          ZeroDivisionError: division by zero
          >>> 0 / 0
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
          ZeroDivisionError: division by zero
          >>> 1 / 0.0
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
          ZeroDivisionError: float division by zero
          >>> 0.0 / 0.0
          Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
          ZeroDivisionError: float division by zero
    

Meanwhile, in Elixir v1.7.1...

    
    
          iex(1)> 1 / 0
          ** (ArithmeticError) bad argument in arithmetic expression: 1 / 0
              :erlang./(1, 0)
          iex(1)> 0 / 0
          ** (ArithmeticError) bad argument in arithmetic expression: 0 / 0
              :erlang./(0, 0)
          iex(1)> 1.0 / 0.0
          ** (ArithmeticError) bad argument in arithmetic expression: 1.0 / 0.0
              :erlang./(1.0, 0.0)
          iex(1)> 0.0 / 0.0
          ** (ArithmeticError) bad argument in arithmetic expression: 0.0 / 0.0
              :erlang./(0.0, 0.0)
    
    

Meanwhile, in Ruby v2.5.1...

    
    
          irb(main):001:0> 1 / 0
          Traceback (most recent call last):
                  3: from /Users/mpope/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
                  2: from (irb):1
                  1: from (irb):1:in `/'
          ZeroDivisionError (divided by 0)
          irb(main):002:0> 0 / 0
          Traceback (most recent call last):
                  3: from /Users/mpope/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
                  2: from (irb):2
                  1: from (irb):2:in `/'
          ZeroDivisionError (divided by 0)
          irb(main):003:0> 1 / 0.0
          => Infinity
          irb(main):004:0> 0.0 / 0.0
          => NaN
    

Meanwhile, in PHP v7.0.8...

    
    
          > echo 1 / 0;
          >
          INF
          Division by zero :1
          > echo 0 / 0;
          >
          NAN
          Division by zero :1
          > echo 1 / 0.0;
          >
          INF
          Division by zero :1
          > echo 0.0 / 0.0;
          >
          NAN
          Division by zero :1
    

Meanwhile, in Node v10.7.0...

    
    
          Infinity
          > 1 / 0
          Infinity
          > 0 / 0
          NaN
          > 1 / 0.0
          Infinity
          > 0 / 0.0
          NaN

~~~
lisael
Meanwhile, in Python...

    
    
      In [1]: 255 + 1 is 256
      Out[1]: True
      In [2]: 256 + 1 is 257
      Out[2]: False
    

Every language has its inconsistencies, when it comes to math, because they
run on real-world computers. All these are "slow" interpreted languages that
allow runtime failures and don't use plain machine integers. Just a different
trade-off.

Anyway, the Inf/NaN trick is not better than the 0 trick in my opinion,
because all subsequent operations result happily in NaN. I've never seen in
any NaN language a program that checks for NaN the result of each and every
division.

with a NaN-kind of language, it would be:

    
    
      a = b/c
      if a == NaN:
        print "oops"
    

with a 0-trick language:

    
    
      a = b/c
      if a == 0 and c == 0:
        print "oops"
    

not THAT different, IMO :)

~~~
PopeDotNinja
When I make a language, there will be a
OuchMyHeadHurtsCommaSpaceGotSomeAspirinQuestionMarkError.

------
dilap
Just yesterday I had a 1/0 bug (code iterating along some line segments that
forgot to account for the possibility of a zero-length segment). If 1/0 was 0,
the code would have worked correctly instead of crashing.

So, there's one data point in favor. :-)

~~~
antidesitter
_code iterating along some line segments that forgot to account for the
possibility of a zero-length segment_

Out of curiosity, could you describe what you were doing and why 1/0 = 0 would
have returned the correct result?

~~~
dilap
Hah, you know what, looking more closely at the code, the bug was not what I
thought, and while the code doesn't crash now, it will still do the wrong
thing!

So the code was given a path described by line segments p0-p1-p2-...pN, and
what it wanted to do was find the point s distance along the path.

It's iterating over pairs of points (pI, pJ) and looking at the segment
length. Is the segment length > the remaining length? If so, then we know our
point is somewhere on the segment (pI, pJ). In particular, it is (remaining
length) divided (segment length) pct along the segment.

This code was dying on zero-length segments (i.e., a repeated point) because
of the divsion above. I wasn't thinking too clearly and fixed the problem by
just skipping 0 length segments.

But actually, the only way that code can even trigger is if the original
distance along the path was negative, in which case we actually just want to
always return the start of the path.

So, in summary, my particular case was buggy either way, and 1/0 behavior
doesn't hurt or help (except it caused a crash instead of an incorrect line in
some cases; not really sure if that's better or worse).

For the case where we do have a zero-length segment, 1/0 = 0 would give
desired behavior (just scale to first point in segment). (But of course, when
it's a zero length segment, _any_ value would be OK, since it would just get
multiplied by zero again.)

------
OscarCunningham
I think a principled mathematical way to say it is that the multiplicative
structure of a field is a group object in the monoidal category of pointed
sets and the smash product (with 0 as the point). So the multiplicative
inverse of 0 really is 0.

------
maury91
So I believe in this article the equation:

y = 1/x

will result in 2 nice asymptotes with a dot in the middle (0,0)

1/0 = 0 doesn't make sense to me, even because lim x->0+ 1/x is infinite and
lim x->0- 1/x is -infinite

so the value that makes more sense for 1/0 is infinite

~~~
joppy
Why infinity rather than negative infinity? Is 1/0 = 1/(-0)?

------
dsego
Doug Crockford argues the same thing in his talk about the future of
programming languages:

The Post JavaScript Apocalypse
[https://youtu.be/99Zacm7SsWQ?t=2434](https://youtu.be/99Zacm7SsWQ?t=2434)

------
glitchc
Please forgive my tone, it's not keeping in the noble spirit of Hacker News.
But here goes:

So that's it. I read your proof. You try cloaking it in pseudo-mathematical
formulation, but what you are really doing is defining division as a derived
operator, rather than the axiomatic operator it is in mathematics. I can say
1= infinity in my universe and as long as I am consistent, it is sound.

You're saying this is a useful property to have, and certainly that holds
merit in certain conditions, but it is not a correct property.

Your article title should be clarified to state "1/0=0 (in my universe)." But
then it wouldn't be controversial would it? After all, this is just an
experiment to gain some visibility for Pony, isn't it?

~~~
kenbellows
The OP didn't invent the definition of fields as defined by additional and
multiplication, with division defined as the Inverse of multiplication. Even
the Wikipedia article on fields
([https://en.wikipedia.org/wiki/Field_%28mathematics%29#Defini...](https://en.wikipedia.org/wiki/Field_%28mathematics%29#Definition))
defines them this way. (Not that Wikipedia is an authority on truth, but I
find that it's a pretty good indicator of what positions are common/widespread
regarding a subject.) It's a bit silly to claim that division is defined as
axiomatic "in mathematics" given how fundamental fields, defined as the OP
defined them, are to modern number theory and mathematics in general.

~~~
glitchc
Nice try, but sorry.

In your link, division is defined as the inverse of multiplication. However,
the inverse of multiplication is one of the axioms of the field, so by
transitivity, division is an axiom as well (it's simply a convenient label for
"the inverse of multiplication"). One can put the name "Division" to some
other axiom or derived property, absolutely, but then "the inverse of
multiplication" still needs to be dealt with. The author, if you note,
conveniently omits the multiplicative inverse from their stated axioms.

I'm far from a pure mathematician, but even I can see through the facade,
implying that it's pretty thin.

------
geoalchimista
My math is rusty but 1 / 0 := 0 implies that 0 * 0 := 1. This contradicts the
definition of a binary field [1], let alone a field of real numbers.

[1]
[https://en.wikipedia.org/wiki/GF(2)](https://en.wikipedia.org/wiki/GF\(2\))

> "It is totally fine to define 1/0 = 0."

No, it's not, at least not useful. If you define it that way, you will not
have a _field_. Then you don't have +, -, *, and / operations with the
commonly assumed behavior. However, it is definitely possible to define some
operation such that 1 `op` 0 := 0, just not the inverse operation of
multiplication.

~~~
emileokada
> However, it is definitely possible to define some operation such that 1 `op`
> 0 := 0, just not the inverse operation of multiplication.

If you read the post this is actually exactly what the OP is saying.

~~~
geoalchimista
Sure, the author spent a long blog essay and didn't get the point across as
clearly as many of the comments here on HN. If this were to be a research
paper it would likely get rejected without a review. Not to mention the whole
point of the idea is _trivial_. Why reinvent a wheel that traps everyone into
the author's whimsical thinking when there is a standard way of doing this
thing (1 / 0 => raise ZeroDivisionError)?

I, for one, will respectfully decline to use any programming language that
defines 1/0 to be 0.

------
vertline2
Pony lang says 1/0=0

I say neigh (sorry if you didn't catch that joke, I'm a little horse).

If x/0 =0 then, since division is inverse of multiplication x= 0*0 this fails
to hold for any x not 0

But the story says there is no defined multiplicative inverse of zero
(undefined) so that they are free to choose any value they want. And they
choose 0.

This is unsatisfactory to me because it seems to break the intuitive pattern
of x/n getting larger as n approaches zero from the positives. 1/4 .25< 1/3
.33 < 1/2 .5 < 1/1 1 >1/0 0 >1/-1 -1 < 1/-2 -.5 < 1/-3 -.333

You see that sign flip thingy happening around 1/0?

Maybe I am misunderstanding.

------
lmm
> But is Pony doing something unsound? Absolutely not. It is totally fine to
> define 1/0 = 0. Nothing breaks and you can’t prove something false.
> Everybody who was making fun of Pony programmers for being ‘bad at math’
> doesn’t actually understand the math behind it.

This is playing semantic games. A whole lot does break: / no longer has its
usual properties, and if you use those usual properties you can certainly
prove false things. It's no different from saying that it's totally fine to
define 2 + 2 = 5 and nothing breaks, you then just have to say that 5 isn't
the arithmetic successor of 4 any more.

~~~
a_wild_dandan
What usual properties does 1 / 0 = 0 break?

~~~
lmm
That dividing by a number means a multiplicative inverse for that number
exists. That a * (b / c) is always equal to b * (a / c). All the things the
article goes through.

------
rlafranchi
It is pretty annoying when you see NaN on a web page. I personally have fallen
into the division by zero trap on numerous occasions.

------
swerveonem
If thing is zero don't divide, like the base case in a recursive function.
This is the maths version of null pointer exception

------
fibo
1/0 is Infinity, to keep consistency with beautiness of Geometry. Consider for
example the stereographic projection.

------
FrozenVoid
A trick to ensure you don't divide by zero in C with minimal overhead(that
converts zeros to 1) x/(y+(y==0))

------
starmole
One thing this all seems to miss that this is about INTEGER division. So any
field argument does not apply?!?

------
jsjohnst
<deleted>

Thought of another reason besides below comment why I was wrong, but thanks
goes to below comment too!

~~~
throwawaymath
Because it has the unfortunate consequence of eliminating the uniqueness
property of fields.

If you allow 0 to have a multiplicative inverse 1/0, then the product of 0 and
1/0 must be equal to the multiplicative identity, which is 1. Then it follows
that 0 = 0 * 0 = 1. From here it's straightforward to prove that _x_ = _y_ for
all _x_ , _y_ in the field _F_.

A multiplicative inverse _is_ a division. You cannot define division by _x_ in
fields without defining multiplication by 1/ _x_ and vice versa. The article
is plainly incorrect in its attempt to refute this point (and in any case,
shouldn't be using field theory to justify its purpose in the first place).

------
anon1234l
1 / 1 = 1 1 / 0.1 = 10 1 / 0.01 = 100 1 / 0.001 = 1000 ....

------
grigjd3
The convention is consistent. I don't find it useful, but it is consistent.

------
z3t4
If you have a cake and divided it in zero parts, where did the cake go ?

------
epx
I.e. a short-circuit means current = 0 because it trips a fuse?

------
danschumann
You know.. dividing is like breaking something up.. If you divide by 2, you
break it up into 2 pieces.. if you divide by 0, from some standpoints, you do
have nothing, because you broke it up into 0 pieces, and 0 pieces is 0.

~~~
hk__2
> You know.. dividing is like breaking something up.. If you divide by 2, you
> break it up into 2 pieces.. if you divide by 0, from some standpoints, you
> do have nothing, because you broke it up into 0 pieces, and 0 pieces is 0.

And dividing by 0.5 is breaking into how many pieces exactly?

~~~
jonshariat
I guess its more flipped. How many pieces equal the whole, not how many pieces
can the whole be broken up into. That's why you can't divide by 0, any number
of nothing can't make a whole.

*disclamer: I have no math background whatso ever

~~~
ggggtez
The function "division" is just like any other function. It takes two inputs,
and gives an output.

The reason it's a useful function is it has some properties:

y=1/x is continuous except where x==0. That is, as you approach 0 from either
side, it grows to either +- infinity. The developers of this language want to
make this function ==0 when x is 0.

You can do that, sure, but it doesn't change the fact that when you go from
+0.0000001 to -0.0000001, you now have 2 non-continuous jumps instead of just
one.

~~~
jonshariat
ah thanks for the explanation!

------
choonway
1/0 = 0 is just plain lazy. So is 0^0 = 1. Now some might argue it is a matter
of how you define the operators. What I say is that then separate them
cleanly. e.g. pow(0,0) = 1 powr(0,0) = NaN

------
j88439h84
Some symbol is failing to render on my android phone.

------
conductr
1/0 = #DIV/0! (Sorry couldn't resist)

------
ramonfritsch
1/0 = +infinity; 1/+infinity = 0; simple.

~~~
zokier
Except machine integer types do not have infinities in them. So not so simple
in the real world.

------
sunseb
It's like in Ruby, when you divide 3/2 you get 1 (integer division) which is
almost never the behavior you want (unless you cast all you numbers to float
which is a pain to do).

~~~
dragonwriter
> It's like in Ruby, when you divide 3/2 you get 1 (integer division) which is
> almost never the behavior you want

I dunno, if I'm dividing a quantized space, which is a fairly common thing to
do, its _exactly_ what I want.

> (unless you cast all you numbers to float which is a pain to do).

Using floats just gets you different wrong answers than using integers, unless
you happened to somehow have ints to start and _want_ a floating point
approximation, which I find is less likely than wanting integer division.

What you really want for exact division where there are integers involved is
to have at least one operand specified as a rational; this also takes less
keystrokes, if its a literal, than changing it to a float to get an inexact
answer.

Related to this, prior to Ruby 2.5, the standard library include "mathn", a
library which monkey-patched all the numeric types so that operations on them
acted pretty much like Ruby had a Scheme-style numeric tower, but since that
has process-wide effects not restricted to where the library is required, that
was deprecated in 2.2 and removed in 2.5.

------
Kiro
> do not mock other programmers

Who is mocking anyone though?

------
anotherevan
What about for really large values of zero?

------
roland00
_Screams into the calculus void!_

------
vmchale
What an absurdly dumb article.

------
gahikr
So x%0 = x for all x?

------
sometimesijust
The set of integers do not form a field so the argument is nonsense.

~~~
FlipperBucket
> The set of integers do not form a field

The set of integers represented by the integer types of pony can be treated as
a field, since they have discrete ranges.

------
EugeneOZ
Oh, so 0*0=1 ?

~~~
esrauch
If a hn title said 1*0=0 could you reply "Oh, so 1=0/0?"

The entire point of the article was suggesting you can define a consistent
system without multiplication and division being entirely symmetrical (as they
already are not)

~~~
JadeNB
> without multiplication and division being entirely symmetrical (as they
> already are not)

What do you mean?

~~~
esrauch
Multiplication by x and division by x are inverses, except there is already
the sole special case of x=0 where that isn't true.

The common way to resolve that is and be consistent is to axiomatically
decide:

1) there is no inverse of * 0

2) 0 is not part of the range permitted for 1/x

The point of the article is that another way to resolve it and be consistent
is to axiomatically decide:

1) there is no inverse of * 0

2) 0 is part of the range permitted for 1/x, and the resulting value is 0.

As in, (x/y) * y=x is true either way only if y!=0. The only difference is
whether when y=0 if it is not true because it is just illegal or if it is not
true because (x/0) * 0 = 0 for all x.

~~~
JadeNB
> As in, (x/y) * y=x is true either way only if y!=0. The only difference is
> whether when y=0 if it is not true because it is just illegal or if it is
> not true because (x/0) * 0 = 0 for all x.

Sure, I understand this claim. What I don't understand is the precise meaning
of the claim "multiplication and division already are not entirely
symmetrical." I don't know any existing technical meaning of "entirely
symmetrical" for a pair of operations, but let's suppose that I switch the
operations in your statement:

> (x/y) * y = x is true [for all x] only if y != 0.

Then I get:

> (x * y)/y = x is true [for all x] only if y != 0.

That's also true. What's the asymmetry?

------
pcagency
isn't a pony an animal you ride? where's the math?

------
yc-kraln
Hey look, /r/badmathematics is leaking

------
abtinf
When setting out to add a new axiom to a heavily studied area of mathematics,
perhaps one should at least formulate an argument that isn't shown to be
incomplete with the most basic wikipedia search.

[https://en.wikipedia.org/wiki/Division_by_zero](https://en.wikipedia.org/wiki/Division_by_zero)

