1

Background

I am trying to learn in C++11 with clang on mac.

Question

As it is said in the book, when float type meets int or lower case in arithmetic, the latter will be converted to float. It is true in cases like:

cout << 9.0 / 5 << endl;

The result yields 1.8000, but when I try to use suffix to ensure the type for the constants like:

cout << 9.0f / 5i << endl;

The result yields 1. I wonder why? Are there different rules or mechanism behind it?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Archimedes520
  • 191
  • 1
  • 9
  • 2
    How did you even get it to compile? `i` is not a built-in numeric suffix (in particular, it doesn't stand for `int` as you seem to believe). For this to compile, there must be an `operator"" i()` defined somewhere in your program; find it, see what it does. – Igor Tandetnik Jul 01 '14 at 14:10
  • 3
    `5i` is an imaginary number (i.e., complex number 0 + 5i) not integral 5. – 101010 Jul 01 '14 at 14:10
  • @40two not out of the box. The compiler does not know what to do with `5i` as Igor said. – tgmath Jul 01 '14 at 14:13
  • @tgmath it seems in Clang v3.4, not necessarily http://coliru.stacked-crooked.com/a/60abcb7c6b065585 – 101010 Jul 01 '14 at 14:15
  • @IgorTandetnik I think I misunderstood the 'i'. Thx for that. But truth to be told, I have no other `operator"" i()` in the test.cpp. I simply include `iostream` and use the line directly. – Archimedes520 Jul 01 '14 at 14:19
  • @40two I don't get how to use this. `5i` is printed as `1` and an assignment to a complex sets it to `(0,0)` See: http://coliru.stacked-crooked.com/a/0b7cea5e012ef911 – tgmath Jul 01 '14 at 15:21
  • @tgmath `std::cout` does not have an overload for `_Complex`. – Shafik Yaghmour Jul 01 '14 at 15:37

1 Answers1

1

Using i as a suffix is an extension which indicates an imaginary constant as opposed to an integer that is also supported by gcc. Without warnings enables clang will just interpret 5i as a complex number. With warning turned on(specifically -Wconversion) it gives the following warning:

warning: imaginary constants are a GNU extension [-Wgnu-imaginary-constant]
std::cout << 9.0f / 5i << std::endl;
                    ^

warning: implicit conversion discards imaginary component: '_Complex float' to 'bool' [-Wconversion]
std::cout << 9.0f / 5i << std::endl;
~~~          ~~~~~^~~~

So it looks like there is no overload for _Complex so the result is being converted to bool. We can see this more clearly using the following examples:

float f = (9.0f / 5 + 0i) ;
std::cout << f << std::endl ;

which outputs 1.8.

If you just want an int literal then no suffix is needed, the other integral suffixes are u, l, ul, ll, ull for unsigned, long, unsigned long, long long and unsigned long long respectively.

So in your case:

9.0f / 5

would be what you want if you want to insure 9.0 is interpreted as a float otherwise it will be interpreted as a double.

5 will be converted to a float as well since the / operator will perform the usual arithmetic conversions on it's operands.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740