Как вычислить максимальное значение перемменой типа unsigned long. (С)
Модератор: Модераторы разделов
-
- Сообщения: 9
- ОС: Gentoo ~amd64
Как вычислить максимальное значение перемменой типа unsigned long.
Ну раз уж есть раздел для начинающих то задам и я свой (возможно для кого то) глупый вопрос.
Хотелось бы узнать быстрый способ вычисления максимального значения переменной типа unsigned long. Именно вычислить, а не взять значение из limits.h.
Хотелось бы узнать быстрый способ вычисления максимального значения переменной типа unsigned long. Именно вычислить, а не взять значение из limits.h.
-
- Сообщения: 782
- Статус: Задвинутый соучастник
Re: Как вычислить максимальное значение перемменой типа unsigned long.
sizeof()
не подойдёт?
не подойдёт?
-
- Сообщения: 39
- ОС: Ubuntu
Re: Как вычислить максимальное значение перемменой типа unsigned long.
Можно какое-нибудь там
Код: Выделить всё
....
unsigned long max=0;
max-=1;
...
Оно перескочит на максимальное значение.
Главный вопрос: зачем оно вам? 8)
Спасибо сказали:
-
- Сообщения: 47
- ОС: GNU
Re: Как вычислить максимальное значение перемменой типа unsigned long.
не будет ли ответом это:
unsigned long i = -1
нужно внимательно посмотреть, что в Стандартах говорится о представлении целых чисел…
unsigned long i = -1
нужно внимательно посмотреть, что в Стандартах говорится о представлении целых чисел…
-
- Сообщения: 47
- ОС: GNU
Re: Как вычислить максимальное значение перемменой типа unsigned long.
Проверил, да unsigned long max = -1 это стандартно.
это преобразование unsigned в signed уже зависит от реализации.
это преобразование unsigned в signed уже зависит от реализации.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как вычислить максимальное значение перемменой типа unsigned long.
-
- Сообщения: 9
- ОС: Gentoo ~amd64
Re: Как вычислить максимальное значение перемменой типа unsigned long.
Можно какое-нибудь там
Код: Выделить всё
.... unsigned long max=0; max-=1; ...
Оно перескочит на максимальное значение.
Спс, я думал что не перескочит, а оказывается перескакивает.
Главный вопрос: зачем оно вам? 8)
Такие вот задачки у Кернигана.
Код: Выделить всё
unsigned long max = ~0;
Что означает ~ в данном случае?
Спасибо всем за ответы, но возник другой вопрос: как тогда вычислить min и max у signed long ?
-
- Сообщения: 39
- ОС: Ubuntu
Re: Как вычислить максимальное значение перемменой типа unsigned long.
~ - это такая штука, которая инвертирует все биты.
Если я где-то не ошибся, для типов со знаками это делается так.
Код: Выделить всё
long allbits = ~((long)0); /* 11111...111 */
long max = allbits >> 1;/* 01111...111*/
long min = max + 1; /* 10000....000 */
Если я где-то не ошибся, для типов со знаками это делается так.
-
- Сообщения: 9
- ОС: Gentoo ~amd64
Re: Как вычислить максимальное значение перемменой типа unsigned long.
ivze писал(а): ↑14.12.2009 20:22~ - это такая штука, которая инвертирует все биты.
Код: Выделить всё
long allbits = ~((long)0); /* 11111...111 */ long max = allbits >> 1;/* 01111...111*/ long min = max + 1; /* 10000....000 */
Если я где-то не ошибся, для типов со знаками это делается так.
Видимо ошиблись, тк при таком раскладе min = 0 max = -1

-
- Сообщения: 47
- ОС: GNU
Re: Как вычислить максимальное значение перемменой типа unsigned long.
ivze,
отрицательные числа могут быть представлены не только в дополнительном коде, это зависит от реализации…
long min = max + 1; /* 10000....000 */
поэтому, полагаю, такое вот выражение решением задачи счтиаться не может.
отрицательные числа могут быть представлены не только в дополнительном коде, это зависит от реализации…
long min = max + 1; /* 10000....000 */
поэтому, полагаю, такое вот выражение решением задачи счтиаться не может.
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Как вычислить максимальное значение перемменой типа unsigned long.
В принципе, это то же самое, что и -1. Разницы абсолютно никакой (в данном случае).
Диапазон для signed можно определить сдвигом вправо на 1 но, вот для беззнакового типа (иначе размножение знака будет работать).
Код: Выделить всё
unsigned long long maxu = ~0; // тут спасает размножение знака
signed long long maxs = maxu >> 1; // тут как раз оно не работает, что хорошо
signed long long mins = maxs + 1;
Спасибо сказали:
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как вычислить максимальное значение перемменой типа unsigned long.
зависит от железа. запись ~0 более безопасна (хотя тоже...)
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
-
- Сообщения: 862
- Статус: Адепт Дзен.
- ОС: Mint, Win7.
Re: Как вычислить максимальное значение перемменой типа unsigned long.
Если не нравится 0
то можно так.
И где сейчас реализовано не в доп. коде?
Код: Выделить всё
unsigned long max = ~0;
то можно так.
Код: Выделить всё
max=max^max;
max=~max;
отрицательные числа могут быть представлены не только в дополнительном коде, это зависит от реализации…
И где сейчас реализовано не в доп. коде?
Desipere in loco
-
- Сообщения: 47
- ОС: GNU
Re: Как вычислить максимальное значение перемменой типа unsigned long.
От железа это не зависит.
Целое беззнаковое число представлено наобром бит, каждый из которых выражает соответсвтующую степень двойки. Таким образом могут быть представлены числа от 0 до 2^N - 1, где N — число битов. ~0 может соответствовать только 2^N - 1 и ничему другому. Это максимальное беззнаковое целое в любой реализации C на любом железе.
Преобразование отрицательного знакового целого в целое беззнаковое тоже стандартная операция. Если преобразуемое число не может быть выражено новым типом, к нему будет прибавляться (или из него вычитаться) 2^N до тех пор, пока оно не попадёт в диапазон представимых значений.
В нашем случае, мы преобразуем непредставимое беззнаковым целым число -1. Чтобы оно попало в представимый диапазн значений, достаточно прибавить к нему 2^N один раз. Получаем то самое 2^N - 1
Это не зависит от способа представления знаковых чисел/железа. Описано в стандартах.
какая разница, где это реализовано сейчас?
даже если сегодня таких реализаций и нет (хотя я и сомневаюсь, что вообще нет), такие реализации могут появиться в любой момент.
вы же не собираетесь переписывать свой код всякий раз, когда сменяется способ представления отрицательных целых?
-
- Сообщения: 9
- ОС: Gentoo ~amd64
Re: Как вычислить максимальное значение перемменой типа unsigned long.
NickLion писал(а): ↑15.12.2009 00:23Код: Выделить всё
unsigned long long maxu = ~0; // тут спасает размножение знака signed long long maxs = maxu >> 1; // тут как раз оно не работает, что хорошо signed long long mins = maxs + 1;
Спасибо конечно, но есть ли другой способ боллее понятный для новичка?
У Кернигана и Ритчи эта задача во второй главе "Типы, операторы и выражения", читателю ещё не известны такие операции как побитовое отрицание или сдвиг.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как вычислить максимальное значение перемменой типа unsigned long.
вместе с компилятором поставляются хидеры с разными MAXINT и прочими константами. Только они везде называются по разному...
-
- Сообщения: 9
- ОС: Gentoo ~amd64
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как вычислить максимальное значение перемменой типа unsigned long.
ок. просто я подумал, что не все об этом знают.
-
- Сообщения: 39
- ОС: Ubuntu
Re: Как вычислить максимальное значение перемменой типа unsigned long.
При побитовом сдвиге вправо типов со знаком левый бит размножается. При побитовом сдвиге вправо беззнаковых типов левые биты заполняются нулями. Вот и узнал сам

Мой метод можно исправить, получится так.
Код: Выделить всё
#include<stdio.h>
int main(int argc, char**argv){
long allbits = ~((long)0); /* 11111...111 */
long max = ((unsigned long)allbits) >> 1;/* 01111...111*/
long min = max + 1; /* 10000....000 */
printf("max=%ld,min=%ld\n", max, min);
return 0;
}
P.S. Кстати, а где внутренний формат хранения чисел не такой, какой я предполагал в этом примере?
-
- Сообщения: 9
- ОС: Gentoo ~amd64
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: Как вычислить максимальное значение перемменой типа unsigned long.
Думал нужен самый эффективный код. Если простой, то вот:
Код: Выделить всё
unsigned long maxu = 0;
for( unsigned long i = 1; i; i *= 2 ) maxu += i;
// maxu = -1; как вариант, тоже что и ~0
long maxs = 0;
for( long i = 1; i > 0; i *= 2 ) maxs += i;
long mins;
for( long i = -1; i < 0; i *= 2 ) mins = i;
-
- Сообщения: 47
- ОС: GNU
-
- Сообщения: 9
- ОС: Gentoo ~amd64
Re: Как вычислить максимальное значение перемменой типа unsigned long.
NickLion писал(а): ↑15.12.2009 16:35Код: Выделить всё
unsigned long maxu = 0; for( unsigned long i = 1; i; i *= 2 ) maxu += i; // maxu = -1; как вариант, тоже что и ~0 long maxs = 0; for( long i = 1; i > 0; i *= 2 ) maxs += i; long mins; for( long i = -1; i < 0; i *= 2 ) mins = i;
Спасибо, то что надо!