What is the correlation between the nth and (n-1)th carry bit being equal and unequal and overflow occuring in the 1's or 2's complement sum - math

I recently found a problem in which the reason for overflow was that the carry bits were unequal. Is that a valid reasoning for overflow in binary arithmetic ?
I saw that some other reasons for overflow were adding two negatives and getting a positive or changing the magnitude of the value when trying to compress a number into the given number of bits.

Related

What is NaN (Not a Number) in the words of a beginner? [closed]

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.

Are there any conventional rules for offset binary arithmetic with fixed size bit-width registers?

Let's say we have two fixed sized binary numbers (8-bit), e.g.
00000101 (5) and 00100000 (32)
The task is to add them in offset binary (excess of 128). Are there any specific rules concerning how to go about this?
Would I for instance first convert both the numbers into offset binary notation, then add them and afterwards subtract the offset (because I added it twice)? But if so, what about overflow, given that the imaginary registers are only 8 bit wide?
Or would I first subtract the excess and then add the second number? Are there any conventional rules when it comes to offset binary arithmetic?
I'm preparing for an exam in computer architecture and computer data arithmetic. This has been a task on an exercise sheet in a previous term. I'v already searched the net extensively for answers but can't seem to find a solid one.
I do not know what the "conventional rules" are for this operation, but I can tell you how I did this operation back when I did machine code.
This method works well when the offset is half the first number that overflows the register. That is the case for you, since the offset is 128 and the 8-bit register overflows on 256. This works especially well when the two numbers you want to add are already in the offset format.
The method is: add the two offset numbers, as unsigned addition and ignoring any overflow, then flip the most significant bit.
In your case, you are adding 10000101 (5 in offset) and 10100000 (32 in offset). Adding those results in 00100101, since there is overflow out of the most significant bit. Flipping the most-significant bit results in 10100101, which is indeed 37 in offset format.
This method may result in overflow, but only when the result is too positive or too negative to fit into the offset format anyway. And in most CPUs the two operations (unsigned addition and flipping the MSB) are practically trivial.

Why a/0 returns Inf instead of NaN in R? [duplicate]

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.

Largest number of bits in error that is guaranteed to be detected in CRC

I have a few questions about CRC:
How can I tell, for a given CRC polynom and a n-bits data, what is the largest number of bits in error that is guaranteed to be detected?
Is it true that ALWAYS - the bigger the polynom degree, the more errors that can be detected from that CRC?
Thanks!
I will assume that "How many errors can it detect" is the largest number of bits in error that is always guaranteed to be detected.
You would need to search for the minimum weight codeword of length n for that polynomial, also referred to as its Hamming distance. The number of bit errors that that CRC is guaranteed to detect is one less than that minimum weight. There is no alternative to what essentially amounts to a brute-force search. See Table 1 in this paper by Koopman for some results. As an example, for messages 2974 or fewer bits in length, the standard CRC-32 has a Hamming distance of no less than 5, so any set of 4 bit errors would be detected.
Not necessarily. Polynomials can vary widely in quality. Given the performance of a polynomial on a particular message length, you can always find a longer polynomial that has worse performance. However a well-chosen longer polynomial should in general perform better than a well-chosen shorter polynomial. However even there, for long message lengths you may find that both have a Hamming distance of two.
It's not a question of 'how many'. It's a question of what proportion and what kind. 'How many' depends on those things and on the length of the input.
Yes.

Is float division always accurate when the two operands are integers and evenly divide?

Can I always trust that when I divide two IEEE 754 doubles that exactly represent integers, I get the exact value?
For example:
80.0/4.0
=> 20.0
The result is exactly 20.0.
Are there some potential values where the result is inaccurate like 19.99999999?
If both integers can be exactly represented by the floating point format (i.e. for doubles, they are less than 253), then yes you will get the exact value.
Floating point is not some crazy fuzzy random algorithm, it does have well-defined deterministic behaviour. Operations that are exact will always give exact answers, and operations that are not exact will round to the representable value (assuming you haven't done anything funny with your rounding modes): "problems" arise when (1) the inputs are not exactly representable (such as 0.1, or 1020), or (2) you're performing multiple operations, some of which may cause intermediate rounding.
According to Wikipedia,
[floating point] division is accomplished by subtracting the divisor's exponent from the dividend's exponent, and dividing the dividend's significand by the divisor's significand.
If one number evenly divides another, then the former's significand should evenly divide the latter's significand. This will give you an exact result.

Resources