5

I am writing a program in Swift that takes the multiplicative inverse of random bytes. Sometimes, the byte is 0, and when the multiplicative inverse is taken, it results in inf.

The multiplicative inverse is being determined using

powf(Float(byte), -1.0)

byte is of type UInt8. If byte is equal to 0, the result is inf as mentioned earlier. How would the multiplicative inverse of 0 be infinity? Wouldn't the multiplicative inverse also be 0 since 0/0's multiplicative inverse is 0/0?

Todd
  • 500
  • 4
  • 10
  • alias's answer is perfect for the IEEE side, but I want to check on your comment that zero's multiplicative inverse makes sense to be zero. A value's multiplicative inverse is the number that when multiplied yields 1. 0*0 is definitely not 1. There are a lots of reasonable arguments about what the result of `pow(0.0,-1.0)` should return (and even 0 would be a reasonable answer; it is what `pow(Int(0),-1)` returns). But it would never be the multiplicative inverse of 0. It would just mean `pow(x, -1)` doesn't always return the multiplicative inverse. – Rob Napier Apr 13 '21 at 17:20
  • (That should have been `pow(Decimal(0), -1)`) – Rob Napier Apr 13 '21 at 17:27

2 Answers2

5

Short answer: By definition. In Swift (and many other languages), floating point numbers are backed by IEEE-754 definition of floats, which is directly implemented by the underlying hardware in most cases and thus quite fast. And according to that standard, division by 0 for floats is defined to be Infinity, and Swift is merely returning that result back to you. (To be precise, 0/0 is defined to be NaN, any positive number divided by 0 is defined to be Infinity, and any negative number divided by 0 is defined to be -Infinity.)

An interesting question to ask might be "why?" Why does IEEE-754 define division by 0 to be Infinity for floats, where one can reasonably also expect the machine to throw an error, or maybe define it as NaN (not-a-number), or perhaps maybe even 0? For an analysis of this, you should really read Kahan's (the designer of the semantics behind IEEE-754) own notes regarding this matter. Starting on page 10 of the linked document, he discusses why the choice of Infinity is preferable for division-by-zero, which essentially boils down to efficient implementation of numerical algorithms since this convention allows skipping of expensive tests in iterative numerical analysis. Start reading on page 10, and go through the examples he discusses, which ends on top of page 14.

To sum up: Floating point division by 0 is defined to be Infinity by the IEEE-754 standard, and there are good reasons for making this choice. Of course, one can imagine different systems adopting a different answer as well, depending on their particular need or application area; but then they wouldn't be IEEE-754 compliant.

alias
  • 28,120
  • 2
  • 23
  • 40
  • "any positive number divided by 0 is defined to be Infinity, and any negative number divided by 0 is defined to be -Infinity" --> There is also -0.0 which reverses the quotient sign. – chux - Reinstate Monica Apr 15 '21 at 10:51
1

Plugging in 0 just means it is 0 divided by some positive number. Then, the multiplicative inverse will be dividing by 0. As you probably know, this is undefined in mathematics, but in swift, it tries to calculate it. Essentially, it keeps subtracting 0 from the number, but never gets a result, so it will output infinity.

Edit: As Alias pointed out, Swift is not actually going through that process of continually subtracting 0. It will just return infinity anytime it is supposed to divide by 0.

  • 1
    This answer is really misleading: Swift (or any other language) isn't trying to compute anything at all: It merely passes these to the underlying hardware, where division by zero of floats is by definition infinity. – alias Apr 13 '21 at 16:56
  • Yeah, that's a good point, I was just trying to explain why that result would be given. – lizard_heart Apr 13 '21 at 16:57