-1

While evaluating the below expression in C, output is zero and not infinity. But as per the C Operator Precedence rule, output should be infinity.

double a=1/(1.0/0.0);
printf("a : %.18le\n", a);

Please explain how gcc compiler evaluates this?

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Huzaifa
  • 31
  • 4
  • 2
    "*But as per the C Operator Precedence rule, output should be inf.*" <- why do you expect that? btw, your question title is misleading... –  May 04 '18 at 13:48
  • 11
    `1.0/0.0` is `inf`, and `n/inf` is `0` –  May 04 '18 at 13:50
  • 1
    @FelixPalmen why `n != 0`, maybe `n != inf`? – yassin May 04 '18 at 13:53
  • 1
    @FelixPalmen: I would have thinked that `0./inf` is still `0.`... – Serge Ballesta May 04 '18 at 13:54
  • yeah right ... just lazily copied it somewhere, comment fixed. –  May 04 '18 at 13:55
  • @FelixPalmen; you got me too with your second comment. – haccks May 04 '18 at 14:06
  • 1
    haha, sorry .. it's friday :D still I think OP should explain his expectation and how this is linked to "precedence" ... maybe the core confusion is something completely different –  May 04 '18 at 14:07
  • I also wonder where precedence comes in here. Does the OP expect that operator precedence ignores brackets and the operation should be `1/1.0/0.0 == (1/1.0)/0.0 == 1.0/0.0 == ` ? Then the expectation is simply not true – Gerhardh May 04 '18 at 15:27

4 Answers4

6

The C standard doesn't dictate how doubles handle NaN and Inf numbers, however with gcc the behavior is dictated by IEEE 754 in strict mode: https://en.wikipedia.org/wiki/IEEE_754

from that article:

The standard defines five exceptions, each of which returns a default value and has a corresponding status flag that (except in certain cases of underflow) is raised when the exception occurs. No other exception handling is required, but additional non-default alternatives are recommended (see below).

The five possible exceptions are:

  • Invalid operation: mathematically undefined, e.g., the square root of a negative number. Returns qNaN by default.

  • Division by zero: an operation on finite operands gives an exact infinite result, e.g., 1/0 or log(0). Returns ±infinity by default.

  • Overflow: a result is too large to be represented correctly (i.e., its exponent with an unbounded exponent range would be larger than emax). Returns ±infinity by default for the round-to-nearest mode.
  • Underflow: a result is very small (outside the normal range) and is inexact. Returns a subnormal or zero by default.
  • Inexact: the exact (i.e., unrounded) result is not representable exactly. Returns the correctly rounded result by default.

However on some platforms, a ieee 754 compatible floating point unit is not available, and you should either enforce a software floating point library or consult the platforms manual on what happens. For instance, arm's fpu's have a 'RunFast' mode, which disables strict compliance.

Some further information: Do any real-world CPUs not use IEEE 754?

Lanting
  • 3,060
  • 12
  • 28
  • Note that Annex F and Annex G in the C11 standard specify the behaviour for C implementations (for floating point and complex floating point arithmetic respectively) that claim conformance to IEC 60559, which is essentially the IEC's name for IEEE 754. Thus, GCC probably is following the C standard — though GCC (8.1.0 on macOS 10.13.4 tested) does not define `__STDC_IEC_559__` which it probably would if it was following the annexes. That said, GCC probably hews rather closely to Annex F and G — I'm a little surprised it doesn't go with that conformance. – Jonathan Leffler May 04 '18 at 15:41
3

Let's break down the expression:

double a = 1 / (1.0 / 0.0);

first the expression 1.0 / 0.0 is evaluated and the result is +infinity.

Then following expression is evaluated: 1.0 / +infinity which results in 0.0 which is the output you get.

The int 1 is promoted to double prior to the evaluation.

All other answer also apply.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
1

Operations involving infinity, as defined by IEEE-754, follow the same rules, basically, as very very large finite numbers. Dividing 1 by n results in a number that gets closer to zero as n gets larger, so the rounded limit is zero.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
1

Dividing something, except infinity, by infinity results in zero. GCC is producing correct result.

haccks
  • 104,019
  • 25
  • 176
  • 264