#c #c 11 #clang #clang-extensions
#c #c 11 #лязг #clang-расширения
Вопрос:
Предыстория
Я пытаюсь изучать C 11 с помощью clang на Mac.
Вопрос
Как сказано в книге, когда тип float соответствует int или нижнему регистру в арифметике, последний будет преобразован в float. Это верно в таких случаях, как:
cout << 9.0 / 5 << endl;
Результат дает 1.8000
, но когда я пытаюсь использовать суффикс, чтобы обеспечить тип для констант, таких как:
cout << 9.0f / 5i << endl;
В результате получается 1
. Интересно, почему? Существуют ли за этим другие правила или механизм?
Комментарии:
1. Как вы вообще смогли его скомпилировать?
i
не является встроенным числовым суффиксом (в частности, он не означаетint
, как вы, кажется, полагаете). Для компиляции этого должно бытьoperator"" i()
определено где-то в вашей программе; найдите его, посмотрите, что он делает.2.
5i
является ли мнимое число (т. Е. комплексное число 0 5i) не целым числом 5.3. @40 два не из коробки. Компилятор не знает, что делать с
5i
как сказал Игорь.4. @tgmath кажется, в Clang v3.4 это не обязательно coliru.stacked-crooked.com/a/60abcb7c6b065585
5. @IgorTandetnik Мне кажется, я неправильно понял «я». Спасибо за это. Но, по правде говоря, у меня нет другого
operator"" i()
в test.cpp . Я просто включаюiostream
и использую строку напрямую.
Ответ №1:
Использование i
в качестве суффикса является расширением, которое указывает на мнимую константу в отличие от целого числа, которое также поддерживается gcc
. Без предупреждений позволяет clang
просто интерпретировать 5i
как комплексное число. При включенном предупреждении (конкретно -Wconversion) выдается следующее предупреждение:
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;
~~~ ~~~~~^~~~
Похоже, что для _Complex
нет перегрузки, поэтому результат преобразуется в bool. Мы можем увидеть это более четко на следующих примерах:
float f = (9.0f / 5 0i) ;
std::cout << f << std::endl ;
который выводит 1.8
.
Если вам просто нужен литерал int, тогда суффикс не требуется, другие целые суффиксы u, l, ul, ll, ull
для unsigned, long, unsigned long, long long and unsigned long long
соответственно.
Итак, в вашем случае:
9.0f / 5
было бы то, что вы хотите, если вы хотите застраховать 9.0
, интерпретируется как число с плавающей точкой, иначе оно будет интерпретироваться как double.
5
также будет преобразовано в значение с плавающей точкой, поскольку /
оператор будет выполнять обычные арифметические преобразования для своих операндов.