As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Why isn't 1/0 == Inf in every language? Is that not the most mathematically correct response?
All the languages I'm familiar with are capable of expressing both Infinite and NaN values, so why would they choose to throw an error or return NaN instead? Is it just to make life harder for scientific application developers? ;-)
Update: We should maybe close this question because I incorrectly thought that 1f/0f == Float.NaN in Java. But I was wrong: it does correctly return Float.Infinity. That was my main confusion; the fact that some languages throw errors instead is understandable, so long as no language returns NaN.
Apart from the fact that 1 / 0 == inf is mathematically highly questionable, the simple reason why it doesn’t work in most programming languages is that 1 / 0 performs an integer division almost universally (exceptions exist).
The result is an integer, and there is simply no way of encoding “infinity” in an integer. There is for floating point numbers, which is why a floating-point division will actually yield an infinite value in most languages.
The same is true for NaN: while the IEEE floating point standard defines a bit pattern that represents a NaN value, integers don’t have such a value; thus such values simply cannot be represented as an integer.
Is that not the most mathematically correct response?
No, because in mathematics, division by zero is simply undefined and infinity is commonly not a value (or not a single value).
The reason that not all languages/libraries return NaN is that (a) zero-division is often the result of a programmer error, since it shouldn't occur at all in mathematically rigorous algorithms, and (b) processors might handle it by going into an exception state, so transforming to NaN would require handling such states, meaning division becomes even more expensive than it already is (compared to, say, summing).
Whilst the limit of 1 / n will tend towards infinity as n approaches zero (from the positive direction) the reason that 1 / 0 <> Inf is that 1 / 0 is undefined (by mathematical definition!).
Why the trolling? But I'll bite. This may vary on the way you build up your operators but the most conventional way to define division is just the functional inverse of multiplication. That is to say c = a/b is defined as c being the unique number such that c*b = a.
Now consider c = 1/0. Is there a unique c such that c*0 = 1? Certainly not within R or C. What if we introduce infinity? You could have a special case that says that 0*Infinity = 1. But then you break a bunch of nice properties of the multiplication operator. That is we would like 2*(0*Infinity) = 2*1 = 2. But we also want the associative property. So (2*0)*Infinity = 0*Infinity = 1.
In general a Field can not be extended to have a multiplicative inverse of 0 in anyway that preserves the properties you want.
That said, I assume you introduced the classic 1/0 = Infinity just to troll. Next question, how come languages don't recognize that 0.9 repeater does not equal 1.
How about 0/0 or -1/0? What if you made a mistake? It is not a good idea to signal the program zero division with an Inf result.
In a Java interactions pane, I see this.
Welcome to DrJava. Working directory is /Users/morrison/Desktop/PhotoPuzzle
> int top = 1;
> int bottom = 0;
> top/bottom
java.lang.ArithmeticException: / by zero
> double topFloat = 1;
> double bottomFloat = 0;
> topFloat/bottomFloat
Infinity
>
Floating point numbers are inexact and can be very close to zero. Making an integer zero is probably seen as a programmer goof. These are likely the two distinct behaviors you see.
Floating point operations can detect several exceptional conditions and react in a couple of different ways:
Setting a status flag that can be later tested.
Immediately generating a trap.
The first mode of operation allows high performance, while the second mode allows immediate notification of possibly erronous operations.
IEEE 754 defines some sane values for the result of operations that raise exceptions (e.g: dividend finite nonzero number and divisor zero → correctly signed INFINITY; 0/0 → Quiet NaN).
The IEEE 754 intention with traps, is that there would be user mode handlers that could inspect the operation, the operands (for Invalid Operation and Divide by Zero exception) or result (for Overflow, Underflow and Inexact exceptions) and exception flags and return a new user-defined result.
In reality, some languages don't even support accessing the exception status flags, let alone set trap handlers.
Even C provides very primitive support for trap handlers, C99 doesn't even define a portable way to set trapping mode, requiring e.g: passing some implementation-defined value to fesetenv(). Implementations will typically raise a SIGFPE, and the user will typically need to access CPU-dependent state to implement a IEEE-754-like trap handler.
Because while 1 / 0 may at times be approximated as INF or some other like value, it's not formally defined as such. On the same front is 10 / 0 < 20 / 0 ? or 0 / 0.
Division a | b by itself isn't defined for b = 0. Therefore implementations of this operation map this case to a special value, to express this concept.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
The community reviewed whether to reopen this question 10 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I still do not understand what a NaN or a (Number which isn´t a real Number) exactly is.
Main question:
What is a NaN value or NaN exactly (in the words of a non-math professor)?
Furthermore i have a few questions about the whole circumstance, which giving me complaints in understanding what a NaN should be, which are not necessary to answer my main question but desired:
What are operations which causing a NaN value as result?
Why is the result of 0.0 / 0.0 declared as undefined? Shouldn´t it be 0?
Why can´t the result of any mathematical operation be expressed by a floating point or integer number? How can it be that a value is unrepresentable?
Why is the square root of a negative number not a real number?
Why is NaN not equivalent to indefinite?
I did not found any understandable explanation of what NaN is for me in the whole Internet, including here on Stack Overflow.
Anyway I want to provide my research as links to places, i have scanned already to find an understandable answer to my question, even if some links go to the same question in other programming languages, but did not gave me the desired clear informations in total:
Wikipedia:
https://en.wikipedia.org/wiki/NaN
https://en.wikipedia.org/wiki/IEEE_754
Other:
http://foldoc.org/Not-a-Number
https://www.youtube.com/watch?v=HN_UmxIVS6M
https://www.youtube.com/watch?v=9EsHjXftO7s
Stack Overflow:
Similar or same questions for other Languages (I provide them as far as i think the base of the understanding is very similar if not the same):
In Java, what does NaN mean?
What is the rationale for all comparisons returning false for IEEE754 NaN values?
(Built-in) way in JavaScript to check if a string is a valid number
JavaScript: what is NaN, Object or primitive?
Not a Number (NaN)
Questions for C++:
What is difference between quiet NaN and signaling NaN?
Checking if a double (or float) is NaN in C++
Why does NaN - NaN == 0.0 with the Intel C++ Compiler?
What is the difference between IND and NAN numbers
Thank you for all helpful answers and comments.
You've asked a series of great questions here. Here's my attempt to address each of them.
What is a NaN value or NaN exactly (in the words of a non-math professor)?
Let's suppose you're working with real numbers - numbers like 1, π, e, -137, 6.626, etc. In the land of real numbers, there are some operations that usually can be performed, but sometimes don't have a defined result. For example, let's look at logarithms. You can take the logarithm of lots of real numbers: ln e = 1, for example, and ln 10 is about 2.3. However, mathematically, the log of a negative number isn't defined. That is, we can't take ln (-4) and get back a real number.
So now, let's jump to programming land. Imagine that you're writing a program that or computes the logarithm of a number, and somehow the user wants you to divide by take the logarithm of a negative number. What should happen?
There's lots of reasonable answers to this question. You could have the operation throw an exception, which is done in some languages like Python.
However, at the level of the hardware the decision that was made (by the folks who designed the IEEE-754 standard) was to give the programmer a second option. Rather than have the program crash, you can instead have the operation produce a value that means "you wanted me to do something impossible, so I'm reporting an error." The way this is done is by having the operation produce the special value NaN ("Not a Number"), indicating that, somewhere in your calculation, you tried to perform an operation that's mathematically not defined.
There are some advantages to this approach. In many scientific computing settings, the code performs a series of long calculations, periodically generating intermediate results that might be of interest. By having operations that aren't defined produce NaN as a result, the programmer can write code that just does the math as they want it to be done, then introduce specific spots in the code where they'll test whether the operation succeeded or not. From there, they can decide what to do. Contrast this with tripping an exception or crashing the program outright - that would mean the programmer either needs to guard every series of floating point operations that could fail or has to manually test things herself. It’s a judgment call about which option is better, which is why you can enable or disable the floating point NaN behavior.
What are operations which causing a NaN value as result?
There are many ways to get a NaN result from an operation. Here's a sampler, though this isn't an exhaustive list:
Taking the log of a negative number.
Taking the square root of a negative number.
Subtracting infinity from infinity.
Performing any arithmetic operation on NaN.
There are, however, some operations that don't produce NaN even though they're mathematically undefined. For example, dividing a positive number by zero gives positive infinity as a result, even though this isn't mathematically defined. The reason for this is that if you take the limit of x / y for positive x as y approaches zero from the positive direction, the value grows without bound.
Why is the result of 0.0 / 0.0 declared as undefined? Shouldn´t it be 0?
This is more of a math question than anything else. This has to do with how limits work. Let's think about how to define 0 / 0. One option would be to say the following: if we look at the expression 0 / x and take the limit as x approaches zero, then we'd see 0 at each point, so the limit should be zero. On the other hand, if we look at the expression x / x and take the limit as x approaches 0, we'd see 1 at each point, so the limit should be one. This is problematic, since we'd like the value of 0 / 0 to be consistent with what you'd find as you evaluated either of these expressions, but we can't pick a fixed value that makes sense. As a result, the value of 0 / 0 gets evaluated as NaN, indicating that there's no clear value to assign here.
Why can´t the result of any mathematical operation be expressed by a floating point or integer number? How can it be that a value is unrepresentable?
This has to do with the internals of IEEE-754 floating point numbers. Intuitively, this boils down to the simple fact that
there are infinitely many real numbers, infinitely many of which have infinitely long non-repeating decimals, but
your computer has finite memory.
As a result, storing an arbitrary real number might entail storing an infinitely long sequence of digits, which we can't do with our finite-memory computers. We therefore have floating point numbers store approximations of real numbers that aren't staggeringly huge, and the inability to represent values results from the fact that we're just storing approximations.
For more on how the numbers are actually stored, and what this means in practice, check out the legendary guide "What Every Programmer Should Know About Floating-Point Arithmetic"
Why is the square root of a negative number not a real number?
Let's take √(-1), for example. Imagine this is a real number x; that is, imagine that x = √(-1). The idea of a square root is that it's a number that, if multiplied by itself, gives you back the number you took the square root of.
So... what number is x? We know that x ≠ 0, because 02 = 0 isn't -1. We also know that x can't be positive, because any positive number times itself is a positive number. And we also know that x can't be negative, because any negative number times itself is positive.
We now have a problem. Whatever this x thing is, it would need to be not positive, not zero, and not negative. That means that it's not a real number.
You can generalize the real numbers to the complex numbers by introducing a number i where i2 = -1. Note that no real numbers do this, for the reason given above.
Why is NaN not equivalent to indefinite?
There's a difference between "indefinite" and "whatever it is, it's not a real number." For example, 0 / 0 may be said to be indeterminate, because depending on how you approach 0 / 0 you might get back 0, or 1, or perhaps something else. On the other hand, √(-1) is perfectly well-defined as a complex number (assuming we have √(-1) give back i rather than -i), so the issue isn't "this is indeterminate" as much as "it's got a value, but that value isn't a real number."
Hope this helps!
For a summary you can have a look at the wikiedia page:
In computing, NaN, standing for not a number, is a member of a numeric
data type that can be interpreted as a value that is undefined or
unrepresentable, especially in floating-point arithmetic. Systematic
use of NaNs was introduced by the IEEE 754 floating-point standard in
1985, along with the representation of other non-finite quantities
such as infinities.
On a practical side I would point out this:
If x or y are NaN floating points: then expressions like:
x<y
x<=y
x>y
x>=y
x==x
are always false. However,
x!=x
will be true and this is a way to check if x is NaN or not (see std::isnan).
Another remark is that when some NaN arise in numerical computations you may observe a big slowdown (this can also be a hint when debugging)
NaN operations on Intel CPUs are likely to generate exceptions which
invoke microcode, so the relative slowdown probably varies greatly
with CPU model.
See NaN slowdown for instance
A floating point number is encoded to a pattern of bits, but not all available bit patterns (for a given number of bits) are used, so there are bit patterns that dont't encode any floating point number. If such patterns are found, they are treated/displayed as NaNs.
Mathematical number systems contain a "set" of values. For example, the positive integers are 0, 1, 2, 3, 4 etc. The negative integers are -1, -2, -3, -4 etc (perhaps -0 too, depending on your branch of mathematics).
In computerland, floating-point numbers additionally have concepts of "infinity" and "not a number", amongst other things. This is like "NULL" for numbers. It means "the floating-point value does not represent a number in the mathematical sense".
They're useful for programmers when they have a float that they don't want to give a number value [yet], and they're also used by the floating-point standards to represent "invalid" results of operations.
You can, for example, get a NaN by dividing zero by zero, an operation with no meaningful value in any branch of mathematics that I'm aware of: how do you share a number of cakes between no people?.
(If you try to do this with integers, which have no concept of NaN or infinity, you instead get a [terribly-named] "floating point exception"; in other words, your program will crash.)
Read more on Wikipedia's article about NaN, which answers pretty much all of your questions.
I'm just curious, why in IEEE-754 any non zero float number divided by zero results in infinite value? It's a nonsense from the mathematical perspective. So I think that correct result for this operation is NaN.
Function f(x) = 1/x is not defined when x=0, if x is a real number. For example, function sqrt is not defined for any negative number and sqrt(-1.0f) if IEEE-754 produces a NaN value. But 1.0f/0 is Inf.
But for some reason this is not the case in IEEE-754. There must be a reason for this, maybe some optimization or compatibility reasons.
So what's the point?
It's a nonsense from the mathematical perspective.
Yes. No. Sort of.
The thing is: Floating-point numbers are approximations. You want to use a wide range of exponents and a limited number of digits and get results which are not completely wrong. :)
The idea behind IEEE-754 is that every operation could trigger "traps" which indicate possible problems. They are
Illegal (senseless operation like sqrt of negative number)
Overflow (too big)
Underflow (too small)
Division by zero (The thing you do not like)
Inexact (This operation may give you wrong results because you are losing precision)
Now many people like scientists and engineers do not want to be bothered with writing trap routines. So Kahan, the inventor of IEEE-754, decided that every operation should also return a sensible default value if no trap routines exist.
They are
NaN for illegal values
signed infinities for Overflow
signed zeroes for Underflow
NaN for indeterminate results (0/0) and infinities for (x/0 x != 0)
normal operation result for Inexact
The thing is that in 99% of all cases zeroes are caused by underflow and therefore in 99%
of all times Infinity is "correct" even if wrong from a mathematical perspective.
I'm not sure why you would believe this to be nonsense.
The simplistic definition of a / b, at least for non-zero b, is the unique number of bs that has to be subtracted from a before you get to zero.
Expanding that to the case where b can be zero, the number that has to be subtracted from any non-zero number to get to zero is indeed infinite, because you'll never get to zero.
Another way to look at it is to talk in terms of limits. As a positive number n approaches zero, the expression 1 / n approaches "infinity". You'll notice I've quoted that word because I'm a firm believer in not propagating the delusion that infinity is actually a concrete number :-)
NaN is reserved for situations where the number cannot be represented (even approximately) by any other value (including the infinities), it is considered distinct from all those other values.
For example, 0 / 0 (using our simplistic definition above) can have any amount of bs subtracted from a to reach 0. Hence the result is indeterminate - it could be 1, 7, 42, 3.14159 or any other value.
Similarly things like the square root of a negative number, which has no value in the real plane used by IEEE754 (you have to go to the complex plane for that), cannot be represented.
In mathematics, division by zero is undefined because zero has no sign, therefore two results are equally possible, and exclusive: negative infinity or positive infinity (but not both).
In (most) computing, 0.0 has a sign. Therefore we know what direction we are approaching from, and what sign infinity would have. This is especially true when 0.0 represents a non-zero value too small to be expressed by the system, as it frequently the case.
The only time NaN would be appropriate is if the system knows with certainty that the denominator is truly, exactly zero. And it can't unless there is a special way to designate that, which would add overhead.
NOTE:
I re-wrote this following a valuable comment from #Cubic.
I think the correct answer to this has to come from calculus and the notion of limits. Consider the limit of f(x)/g(x) as x->0 under the assumption that g(0) == 0. There are two broad cases that are interesting here:
If f(0) != 0, then the limit as x->0 is either plus or minus infinity, or it's undefined. If g(x) takes both signs in the neighborhood of x==0, then the limit is undefined (left and right limits don't agree). If g(x) has only one sign near 0, however, the limit will be defined and be either positive or negative infinity. More on this later.
If f(0) == 0 as well, then the limit can be anything, including positive infinity, negative infinity, a finite number, or undefined.
In the second case, generally speaking, you cannot say anything at all. Arguably, in the second case NaN is the only viable answer.
Now in the first case, why choose one particular sign when either is possible or it might be undefined? As a practical matter, it gives you more flexibility in cases where you do know something about the sign of the denominator, at relatively little cost in the cases where you don't. You may have a formula, for example, where you know analytically that g(x) >= 0 for all x, say, for example, g(x) = x*x. In that case the limit is defined and it's infinity with sign equal to the sign of f(0). You might want to take advantage of that as a convenience in your code. In other cases, where you don't know anything about the sign of g, you cannot generally take advantage of it, but the cost here is just that you need to trap for a few extra cases - positive and negative infinity - in addition to NaN if you want to fully error check your code. There is some price there, but it's not large compared to the flexibility gained in other cases.
Why worry about general functions when the question was about "simple division"? One common reason is that if you're computing your numerator and denominator through other arithmetic operations, you accumulate round-off errors. The presence of those errors can be abstracted into the general formula format shown above. For example f(x) = x + e, where x is the analytically correct, exact answer, e represents the error from round-off, and f(x) is the floating point number that you actually have on the machine at execution.
What happens if you divide by Zero on a Computer?
In any given programming languange (I worked with, at least) this raises an error.
But why? Is it built in the language, that this is prohibited? Or will it compile, and the hardware will figure out that an error must be returned?
I guess handling this by the language can only be done, if it is hard code, e.g. there is a line like double z = 5.0/0.0; If it is a function call, and the devisor is given from outside, the language could not even know that this is a division by zero (at least a compile time).
double divideByZero(double divisor){
return 5.0/divisor;
}
where divisor is called with 0.0.
Update:
According to the comments/answers it makes a difference whether you divide by int 0 or double 0.0.
I was not aware of that. This is interesting in itself and I'm interested in both cases.
Also one answer is, that the CPU throws an error. Now, how is this done? Also in software (doesn't make sense on a CPU), or are there some circuits which recognize this? I guess this happens on the Arithmetic Logic Unit (ALU).
When an integer is divided by 0 in the CPU, this causes an interrupt.¹ A programming language implementation can then handle that interrupt by throwing an exception or employing whichever other error-handling mechanisms the language has.
When a floating point number is divided by 0, the result is infinity, NaN or negative infinity (which are special floating point values). That's mandated by the IEEE floating point standard, which any modern CPU will adhere to. Programming languages generally do as well. If a programming language wanted to handle it as an error instead, it could just check for NaN or infinite results after every floating point operation and cause an error in that case. But, as I said, that's generally not done.
¹ On x86 at least. But I imagine it's the same on most other architectures as well.
Prompted by a spot of earlier code golfing why would:
>NaN^0
[1] 1
It makes perfect sense for NA^0 to be 1 because NA is missing data, and any number raised to 0 will give 1, including -Inf and Inf. However NaN is supposed to represent not-a-number, so why would this be so? This is even more confusing/worrying when the help page for ?NaN states:
In R, basically all mathematical functions (including basic
Arithmetic), are supposed to work properly with +/- Inf and NaN as
input or output.
The basic rule should be that calls and relations with Infs really are
statements with a proper mathematical limit.
Computations involving NaN will return NaN or perhaps NA: which of
those two is not guaranteed and may depend on the R platform (since
compilers may re-order computations).
Is there a philosophical reason behind this, or is it just to do with how R represents these constants?
This is referenced in the help page referenced by ?'NaN'
"The IEC 60559 standard, also known as the ANSI/IEEE 754 Floating-Point Standard.
http://en.wikipedia.org/wiki/NaN."
And there you find this statement regarding what should create a NaN:
"There are three kinds of operations that can return NaN:[5]
Operations with a NaN as at least one operand.
It is probably is from the particular C compiler, as signified by the Note you referenced. This is what the GNU C documentation says:
http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html
" NaN, on the other hand, infects any calculation that involves it. Unless the calculation would produce the same result no matter what real value replaced NaN, the result is NaN."
So it seems that the GNU-C people have a different standard in mind when writing their code. And the 2008 version of ANSI/IEEE 754 Floating-Point Standard is reported to make that suggestion:
http://en.wikipedia.org/wiki/NaN#Function_definition
The published standard is not free. So if you are have access rights or money you can look here:
http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4610933
The answer can be summed up by "for historical reasons".
It seems that IEEE 754 introduced two different power functions - pow and powr, with the latter preserving NaN's in the OP case and also returning NaN for Inf^0, 0^0, 1^Inf, but eventually the latter was dropped as explained briefly here.
Conceptually, I'm in the NaN preserving camp, because I'm coming at the issue from viewpoint of limits, but from convenience point of view I expect current conventions are slightly easier to deal with, even if they don't make a lot of sense in some cases (e.g. sqrt(-1)^0 being equal to 1 while all operations are on real numbers makes little sense if any).
Yes, I'm late here, but as R Core member who was involved in this design, let me recall what I commented above. NaN preserving and NA preserving work "equivalently" in R, so if you agree that NA^0 should give 1, NaN^0 |-> 1 is a consequence.
Indeed (as others said) you should really read R's help pages and not C or
IEEE standards, to answer such questions,
and SimonO101 correctly cited
1 ^ y and y ^ 0 are 1, always
and I'm pretty sure that I was heavily involved (if not the author) of that.
Note that it is good, not bad, to be able to provide non-NaN answers, also in cases other programming languages do differently.
The consequence of such a rule is that more things work automatically correctly;
in the other case, the R programmer would have been urged to do more special casing herself.
Or put differently, a simple rule as the above (returning non-NaN in all cases) is a good rule, because it propagates continuity in a mathematical sense: lim_x f(x) = f(lim x).
We have had a few cases where it was clearly advantageous (i.e. did not need special casing, I'm repeating..) to adhere to the above "= 1" rule, rather than to propagate NaN. As I said further up, the sqrt(-1)^0 is also such an example, as 1 is the correct result as soon as you extend to the complex plane.
Here's one reasoning. From Goldberg:
In IEEE 754, NaNs are often represented as floating-point numbers with
the exponent e_max + 1 and nonzero significands.
So NaN is a floating-point number, though with a special meaning. Raising a number to the power zero sets its exponent to zero, therefore it will no longer be NaN.
Also note:
> 1^NaN
[1] 1
One is a number whose exponent is zero already.
Conceptually, the only problem with NaN^0 == 1 is that zero values can come about at least four different ways, but the IEEE format uses the same representation for three of them. The above formula equality sense for the most common case (which is one of the three), but not for the others.
BTW, the four cases I would recognize would be:
A literal zero
Unsigned zero: the difference between two numbers that are indistinguishable
Positive infinitesimal: The product or quotient of two numbers of matching sign, which is too small to be distinguished from zero.
Negative infinitesimal: The product or quotient of two numbers of opposite sign, which is too small to be distinguished from zero.
Some of these may be produced via other means (e.g. literal zero could be produced as the sum of two literal zeros; positive infinitesimal by the division of a very small number by a very large one, etc.).
If a floating-point recognized the above, it could usefully regard raising NaN to a literal zero as yielding one, and raising it to any other kind of zero as yielding NaN; such a rule would allow a constant result to be assumed in many cases where something that might be NaN would be raised to something the compiler could identify as a constant zero, without such assumption altering program semantics. Otherwise, I think the issue is that most code isn't going to care whether x^0 might would NaN if x is NaN, and there's not much point to having a compiler add code for conditions code isn't going to care about. Note that the issue isn't just the code to compute x^0, but for any computations based on that which would be constant if x^0 was.
If you look at the type of NaN, it is still a number, it's just not a specific number that can be represented by the numeric type.
EDIT:
For example, if you were to take 0/0. What is the result? If you tried to solve this equation on paper, you get stuck at the very first digit, how many zero's fit into another 0? You can put 0, you can put 1, you can put 8, they all fit into 0*x=0 but it's impossible to know which one the correct answer is. However, that does not mean the answer is no longer a number, it's just not a number that can be represented.
Regardless, any number, even a number that you can't represent, to the power of zero is still 1. If you break down some math x^8 * x^0 can be further simplified by x^(8+0) which equates to x^8, where did the x^0 go? It makes sense if x^0 = 1 because then the equation x^8 * 1 explains why x^0 just sort of disappears from existence.
This is an odd one I'm puzzled about. I recently noticed at the Gnu Octave prompt, it's possible to enter in negative zeroes, like so:
octave:2> abomination = -0
And it remembers it, too:
octave:3> abomination
abomination = -0
In the interest of sanity, negative zero does equal regular zero. But I also noticed that the sign has some other effects. Like these:
octave:6> 4 * 0
ans = 0
octave:7> 4 * -0
ans = -0
octave:8> 4 / 0
warning: division by zero
ans = Inf
octave:9> 4 / -0
warning: division by zero
ans = -Inf
As one can see, the sign is preserved through certain operations. But my question is why. This seems like a radical departure from standard mathematics, where zero is essentially without sign. Are there some attractive mathematical properties for having this? Does this matter in certain fields of mathematics?
FYI: Matlab, which octave is modeled after, does not have negative zeros. Any attempts to use them are treated as regular zeros.
EDIT:
Matlab does have negative zeros, but they are not displayed in the default output.
Signed zero are part of the IEEE-754 formats, and their semantics are completely specified by those formats. They turn out to be quite useful, especially when dealing with complex branch cuts and transformations of the complex plane (see many of W. Kahan's writings on the subject for more details, such as the classic "Branch Cuts for Complex Elementary Functions, or Much Ado about Nothing's Sign Bit").
Short version: negative zero is often a good thing to have in numerical calculations, and programs that try to protect users from encountering it are often doing them a disservice. FWIW, MATLAB does seem to use negative zero as well, but since it prints numbers using the host's printf routine, they display the same as positive zero on Windows.
See this discussion on the MATLAB forums for more details on signed zero in MATLAB.
IEEE-754 floating point numbers have this property too. It might come in handy for limits and infinities. For example, the limit of 1/x with x → +∞ is 0, but the function approaches from the positive side of the axis, with x → −∞ the function approaches from the negative side so one might give the limit as −0, in that case.
Signed Zero
Signed zero echoes the mathematical
analysis concept of approaching 0 from
below as a one-sided limit, which may
be denoted by x → 0−, x → 0−, or x →
↑0. The notation "−0" may be used
informally to denote a negative number
that has been rounded to zero. The
concept of negative zero also has some
theoretical applications in
statistical mechanics and other
disciplines.