Форум программистов, компьютерный форум CyberForum.ru

U, L, F в константах - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Hesh00
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 11
27.04.2012, 22:49     U, L, F в константах #1
Подскажите, пожалуйста, зачем использовать U, L, F в константах? В двух книгах прочитал, никак не получается разобраться.

Например, мы задаём константу:
C++
1
const unsigned a = 10;
Так зачем здесь ещё использовать "U"?

Или вышеприведённый код эквивалентен:
C++
1
const int a = 10U;
?

Или вот, читаю:
"Чтобы использовать двубайтовый символьный литерат (т.е. константу типа wchar_t), предварите нужный символ буквой L. Например, так.
C++
1
2
wchar_t wc;
wc = L'A';
Так зачем нам нужна буква "L", если мы уже определили тип как "wchar_t"?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
27.04.2012, 22:59     U, L, F в константах #2
это литерные константы, используется для явного указания типа.
L или l - long
U или u - unsigned
F или f - float
например, 0F указывает компилятору что вам нужен 0 типа float (с плавающей точкой), а не 0 типа int.
Hesh00
0 / 0 / 0
Регистрация: 01.03.2012
Сообщений: 11
03.05.2012, 20:18  [ТС]     U, L, F в константах #3
Ну, это понятно (читать книги умею).
Я не понимаю, зачем это нужно. Или это для того, чтобы использовать тот же ноль с плавающей точкой напрямую в выражении, а не присваивая его предварительно переменной?
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
03.05.2012, 21:33     U, L, F в константах #4
Я сам особо не встречал применения этих констант.
Приведу пример, не самый удачный:
допустим есть две перегруженных функции
C++
1
2
3
4
5
6
void Foo(int a){
// действия над а
}
void Foo(long b){
// действия над b
}
теперь если мы вызовем функции Foo(5), то выполнится либо первая версия, либо компилятор ругнется что есть два кандидата функции.
чтобы явно вызвать вторую версию нужно указать Foo(5L).
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
03.05.2012, 22:24     U, L, F в константах #5
Вот пример

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int r = 256;
 
int main (void)
{
  long long x = 2147483392 * r;
  long long y = 2147483392LL * r;
 
  printf("%lld\n", x);
  printf("%lld\n", y);
 
  return 0;
}
результат:

Код
-65536
549755748352
Добавлено через 8 минут
Ещё один пример:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int a = 31;
int b = 31;
 
int main (void)
{
  int x = (1 << a) >> b;
  int y = (1u << a) >> b;
 
  printf("%d\n", x);
  printf("%d\n", y);
 
  return 0;
}
Результат:

Код
-1
1
Добавлено через 1 минуту
С плавающей константой пример не получается, потому что под intel'овские процессоры компиляторы работают нечестно (т.е. не так, как того требует стандарт). Завтра на работе попробую на sparc'е
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
03.05.2012, 22:30     U, L, F в константах #6
Evg, можно поподробней пожалуйста, что требует стандарт в данном случае?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
03.05.2012, 22:42     U, L, F в константах #7
C
1
long long x = 2147483392 * r;
В правой части мы видим константу типа int и переменную r типа int. Поэтому умножение над двумя int'ами произойдёт в формате int (т.е. 32-битное умножение, которое вызовет переполнение и откидывание старшей части). Затем при присваивании int'а в long long произойдёт преобразование типов int -> long long (т.е. int32 -> int64)

C
1
long long y = 2147483392LL * r;
В правой части стоит константа типа long long и переменная типа int. При арифметической операции над аргументами разных типов по стандарту более узкий аргумент будет приведён к типу более широкого аргумента и операция будет выполнена в типе более широкого аргумента. Поэтому сначала выполнится преобразование int -> long long для переменной "r", и только после этого будет выполнено 64-битное умножение (уже без переполнения)

Во втором примере со сдвигами вся фишка в том, что операция сдвига вправо на большинстве процессоров по разному выполняется для знаковых и беззнаковых типов. Чтобы результаты отличались, надо чтобы у сдвигаемого аргумента самый старший бит был равен единице. В своём примере я это сделал при помощи операции сдвига влево (которая одинаково работает как для знаковых, так и беззнаковых типов)
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
03.05.2012, 22:44     U, L, F в константах #8
С целочисленными то все понятно. Я про float, ты упомянул, что компиляторы под x86 хитрят.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
03.05.2012, 22:48     U, L, F в константах #9
Цитата Сообщение от Toshkarik Посмотреть сообщение
С целочисленными то все понятно. Я про float, ты упомянул, что компиляторы под x86 хитрят.
На интеле вся плавающая арифметика аппаратно поддержана только 80-битная, поэтому у них принято все операции проводит в формате long double. Т.е. выражение

C
1
2
3
4
double a;
float b;
 
a = a + c;
по стандарту должно считаться как

C
1
a = a + (double)b;
но компиляторы построят код

C
1
a = (double)((long double)a + (long double)b);
У gcc была какая-то опция, которая заставляет компилятор строить честный код (но он будет работать медленнее), но не помню, как называется. Возможно, что и у других компиляторов есть. А может другие компиляторы строят честно, хрен его знает. Для надёжности посмотрю на работе, sun'овский компилятор точно работает честно. Я просто intel'овскую архитектуру почти не знаю
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
03.05.2012, 23:13     U, L, F в константах #10
Ааааа, понятно про что Вы. Я же читал где то, у Дейтелов вроде, что все числа с плавающей точкой изначально представляются как double, а не long double. Но это С++, возможно в Си по другому.

Добавлено через 7 минут
Перепутал немного, это относится к константам.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.05.2012, 12:13     U, L, F в константах
Еще ссылки по теме:

Turbo Pascal Вычислите выражение при заданных константах

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
04.05.2012, 12:13     U, L, F в константах #11
Про плавающие:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int r = 255;
 
int main (void)
{
 int x = 8388607.0 * r;
 int y = 8388607.0f * r;
 
 printf("%d\n", x);
 printf("%d\n", y);
 
 return 0;
}
Результат на sparc'е:

Код
$ gcc t.c
$ ./a.out
2139094785
2139094784
В случае intel'а потребовалась дополнительная опция

Код
$ gcc t.c -ffloat-store
$ ./a.out
2139094785
2139094784
Yandex
Объявления
04.05.2012, 12:13     U, L, F в константах
Ответ Создать тему
Опции темы

Текущее время: 05:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru