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 w…
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 th…
1/0 = 0
181–190 of 593 posts
Re: 1/0 = 0
#182Earlier quoted context omitted.
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?
Take the limit as x goes to 0 of (17*x)/(x). Both numerator and denominator go to 0, so this is a representation of 0/0. The limit is then equal to 17.
Re: 1/0 = 0
#183My 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…
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
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.
Re: 1/0 = 0
#184Earlier quoted context omitted.
This is not true if you say division by 0 is undefined or +inf either. It really is totally fine.
No, you are assuming that 1/0= "undefined" where "undefined" is a magical value. It's not. It literally means 'That operation has no definition, and there is no reasonable result to return'. Many languages handle this in a practical way by creating a special value "undefined", "NaN", or others that has special properties. But let's be clear that "0" is a normal number in the real number space, as so expectations abou…
Re: 1/0 = 0
#185Earlier quoted context omitted.
It’s common for 1/0 = 0 to be exactly what you want. Array average for example. That said raising exception would be the only consistent behavior if a language supports that.
Common compared to what? Taking an average of an empty array is nonsensical.
Let’s say some program calculates the mean of an array and then adds that mean to some accumulator.
For purposes of updating the accumulator, the mean of an empty array is perfectly well-defined: it should add nothing to the accumulator (add 0).
This might be a major operating requirement for the mean function, such that rather than guarding or pattern-matching on an empty array and handling a failure is far worse than having a better 0-length convention.
Consider the difference between the “head” function of some List type, which has to either raise an exception or wrap the return value in some Maybe structure, because it’s literally not definable, vs the “length” function which has an obvious natural definition for empty arrays that is often highly preferred to some design where length(empty_list) throws an exception and everyone has to handle it in little bits of custom code to specify 0.
To me this topic is all about usability and not about some parochial claim that some operation is nonsensical.
Re: 1/0 = 0
#186Perhaps it's not a good design to have division as an operator a programming language? Just like
Maybe i = ParseInt("foo")
one should also do this for division:
Maybe 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.
Re: 1/0 = 0
#187Edit: 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 w…
Explicit might be better than implicit most of the times, but it is possible to be too explicit.
That said, we can achieve this, although it's probably a bit trickier than you'd think at first. The best option I know is called "refinement typing", which basically allows you to specify types as subsets (ie "the set of integers which are not 0") and automatically verifies whether your functions actually return a value in the subset.
Liquid Haskell[1] is an example of a system you can use today to play with the idea. It uses an automatic logic solver (Z3) under the hood to automatically prove that your refinements hold. (For example, I believe it should be able to automatically verify that the function f x = abs x + 1 will never be 0.)
Re: 1/0 = 0
#188Earlier quoted context omitted.
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?
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.
Re: 1/0 = 0
#189> 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 de…
> (x / y) * y equals x Even without Pony's assumption, that's only true when y != 0.
Re: 1/0 = 0
#190Oh, so 0*0=1 ?
> So it is _not_ a theorem that a * (b / 0) = b * (a / 0) As the article explains, the whole issue about dividing by 0 is the lack of multiplicative inverse. If you define division for 0 as something other than multiplication by the multiplicative inverse, there is no longer an issue doing the division. Hope that helps.