IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Работа с битами
сообщение
Сообщение #1


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Хочется видите ли с битами работать. Но даже в тот же Longint они не влазят.
Вот такой маразм не прокатывает:
program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
p: pointer;
pSize: integer;
i: integer;

begin
pSize := SizeOf(longint)*8+1;
WriteLn(pSize);
GetMem(p,pSize);
FillChar(p^,pSize,0);
Integer(p^) := 4294967296;
for i := pSize-1 downto 0 do
Write((Integer(p^) shr i)and $1);
WriteLn;
FreeMem(p,pSize);
readln;
end.

Объявлять массив Байтов и делать перегрузку +- не интересно.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Ну, с таким-то значением ничего перегружать не надо:
type
PInt64 = ^Int64; // Можно работать и с QWord, причем безо всяких извращений с выделением памяти...
var
p : pointer;
pSize : integer;
i : integer;
begin
pSize := SizeOf(longint)*8+1;
WriteLn(pSize);
GetMem(p,pSize);
FillChar(p^,pSize,0);
PInt64(p)^ := 4294967296;
for i := pSize-1 downto 0 do
Write((PInt64(p)^ shr i)and $1);
WriteLn;
FreeMem(p,pSize);
readln;
end.
, а вот если значение будет больше 18446744073709551615 (максимум для QWord - вот тогда точно придется принимать меры)

P.S. Вопрос на засыпку: на кой ты выделяешь 33 байта, если тебе достаточно 33 битов для хранения значения?

Сообщение отредактировано: IUnknown -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Ну 512бит это уже лучше, но все равно не много smile.gif

Когда игрался с типами забыл 8 убрать.

А есть какой-то битовый тип кроме boolean?

Сообщение отредактировано: sheka -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


512 бит - это 64 байта, а тип Int64 - это 64 бита...

Цитата
А есть какой-то битовый тип кроме boolean?
Нет. Ко всему прочему, Boolean - ни разу не битовый. То, что он может хранить только 2 значения - еще ни о чем не говорит... Ты задачу-то озвучь, может что-то кроме таких извращений можно будет придумать. Чего ты привязался к битам?

... (Показать/Скрыть)


Сообщение отредактировано: IUnknown -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Что-то я лишний раз на 8 умножил (логарифм от того большого числа брал).
Но если массив booleanoв, то можно делать приведение типов word(a[i]) и будет выдавать нужный результат при той же занимаемой памяти что и у битов.
Задачу не помню, сродни вот этой Flip, но там надо было как-то передвигать штуки типа японского кроссворда. Обычно из-за того, что не хватает разрядной сетки пользуюсь рекурсией, хотя очень бы хотелось пользоваться такими штуками
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Но если массив booleanoв, то можно делать приведение типов word(a[i]) и будет выдавать нужный результат при той же занимаемой памяти что и у битов.
Не будет. Либо тебе очень повезло и ты натолкнулся на простое совпадение, либо результат будет, но неправильный. Массив Boolean-ов никогда не занимает в памяти места меньше, чем по 1 байту на значение...

Попробуй показать тестовый код, скажем, который вот так же, как мой напечатает содержимое Integer-а через массив Boolean-ов, при этом места этот самый массив будет занимать ровно 2 байта (как и сам Integer) smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Цитата
Не будет. Либо тебе очень повезло и ты натолкнулся на простое совпадение, либо результат будет, но неправильный. Массив Boolean-ов никогда не занимает в памяти места меньше, чем по 1 байту на значение...
Не ожидал. Совсем не ожидал. А почему Boolean занимает ВСЕГДА 1 байт? Зачем оно так?

Это АДА?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(sheka @ 9.07.2011 0:01) *
Не ожидал. Совсем не ожидал. А почему Boolean занимает ВСЕГДА 1 байт? Зачем оно так?

А чего тут ожидать/не_ожидать? Берешь проверяешь, sizeof всегда под рукой.

Идеология простая.
1. Архитектура памяти - байтовая. То есть невозможно адресовать бит в системе команд.
2. Каждая переменная должна иметь свой адрес.

Идея побитового доступа сама по себе имеет право на жизнь. Но либо это специальная конструкция языка, либо надо менять всю архитектуру.

У меня когда-то был модуль для побитового доступа к памяти. Сделать его нетрудно. Скорость в те времена падала заметно, сейчас ситуация может быть лучше. Все зависит от того, КАК реализовать )).


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Да это понятно, что sizeof все прекрасно выдает, так и проверял, но почему-то на подсознании думал раз 2 значения, значит бит.
Идеология кого?
Архитектура языка?
И в какую сторону его реализовывать? smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
А почему Boolean занимает ВСЕГДА 1 байт? Зачем оно так?
Стоп... Похоже, FPC умеет-таки упаковывать биты (в Дельфи, однако, этого нет до сих пор, хотя просили давно):

type
bit = 0 .. 1;
bitarr = bitpacked array[1 .. 16] of bit;

var
X : word;
i : integer;
ba : bitarr absolute X;
begin
writeln(sizeof(ba));
X := 5458;
for i := 16 downto 1 do //
write(ba[i]);
writeln;
end.
=>
2
0001010101010010



Цитата
Это АДА?
ADA - это Ассоциация Дантистов Америки, а это - Ada smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(sheka @ 9.07.2011 0:38) *
Идеология кого?
Программирования.

Цитата
Архитектура языка?
Компьютера.

Цитата
И в какую сторону его реализовывать? smile.gif
Ну как.. Нужно тебе 100 бит. Вызываешь процедуру (свою) MakeBitArray(A,100). Она реально заводит массив из 13 байт. Потом ты обращаешья к нему функцией GetBit(A,55): integer, которая дает тебе 55-ое значение из того массива (используя всякие маски).

Но погоди мутить, volvo877 что-то нарыл, похоже..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Стремный метод однако.
Лучше ничего нет?

Дык получается, что первые 7 бит booleana - вечные 0 ?

Сообщение отредактировано: sheka -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(sheka @ 9.07.2011 0:59) *
Дык получается, что первые 7 бит booleana - вечные 0 ?

Это почему?? никто не гарантировал..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Дык получается, что первые 7 бит booleana - вечные 0 ?
Кто тебе сказал, что Boolean - это только 0 и 1? Не было такого уговора. False - да, это 0. А вот насчет True ограничений не было:

var
b : boolean;
begin
b := boolean(255);
writeln(b);
writeln(byte(b));
end.

Все, что не 0 - True... Так что не вечные нули. Смотря ка используешь Boolean...

Цитата
Стремный метод однако.
Хм... Тебя не поймешь. То тебе не так, это - не этак. Скажи, что нужно... Лучше bitpacked все равно вряд ли сделаешь...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Кроме прочего, если заводишь boolean переменную динамически, в первый момент там все, что угодно. И, как сказал IU (сорри, очень длинно..)), трактуется так: 0 - ложь, не 0 - правда.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Делфи на такую штуку иероглифы выводит. Не нравится ему писать TRUE если не 00000001 smile.gif

Это-то и нужно, просто это не интересно, до этого даже я додумался smile.gif
Лучше и не надо, меня именно и интересуют извращения, т. е. посмотреть что можно вытащить из возможностей.

Ну как бы в Си такое же понятие True и False, и именно поэтому как зарезервированные слова они появились позже и то в библиотеках, если не ошибаюсь. Зачем тогда было выдумывать boolean? для простой смены True = not False ?

Сообщение отредактировано: sheka -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(sheka @ 9.07.2011 1:18) *
Ну как бы в Си такое же понятие True и False, и именно поэтому как зарезервированные слова они появились позже и то в библиотеках, если не ошибаюсь. Зачем тогда было выдумывать boolean? для простой смены True = not False ?
В Си это не понятие, а интерпретация.
Для лучшей типизации.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Лучше и не надо, меня именно и интересуют извращения, т. е. посмотреть что можно вытащить из возможностей.
Я б не рекомендовал тебе заниматься подобными извращениями. По той простой причине, что такие вот "финты ушами" мало того, что малопереносимы между разными компиляторами (как ты уже успел убедиться, код, работающий под FPC, не работает при использовании Дельфи), так еще и при выходе новой версии того же компилятора могут быть проблемы (да, достаточно вспомнить те ужесточения, которые были сделаны при переходе от FPC 2.2.x к 2.4.0, многое из того, что было разрешено в ветке 2.2, в ветке 2.4 делать нельзя). Так что тут игра не стоит свеч. Или будешь переписывать код под каждую версию компилятора smile.gif

Цитата
Зачем тогда было выдумывать boolean? для простой смены True = not False ?
Знаешь, в том виде, в котором оно есть в FPC/Дельфи - лучше б этого типа вообще не было. Изначально это задумывалось совсем в другом виде. Вот в Турбо-Паскале более правильная реализация типа Boolean. Тот код, который я приводил в 14-ом сообщении там тоже будет компилироваться, но writeln(byte(b)) выведет не 255, а 1. И любое ненулевое значение, преобразованное к Boolean, также вернется как 1.

Но в Модуле, Haskell-е и Аде еще более корректная реализация: там это именно перечисление, и преобразовать Integer -> Boolean и обратно обычным тайпкастом просто нельзя. Вот именно так это и задумывалось. Хаки - они для программ смертельны...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Цитата
Но в Модуле, Haskell-е и Аде еще более корректная реализация: там это именно перечисление

Расскажите о перечислениях более подробно: их представление, размер, кол-во элементов.
SizeOf выдает 4байта. Значит кол-во 232?

Интервальный тип округляется к большему целому кол-ву байт, но не больше 8ми?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
SizeOf выдает 4байта
Ты опять совершаешь ту же самую ошибку. Пойми, что на SizeOf нельзя полагаться, он будет выдавать разные значения в зависимости от
1) режима, в котором происходит компиляция;
2) использования настроек компилятора или директив.

В частности, на размер типа-перечисления влияет использование директивы $PACKENUM (минимальное количество байт, используемое для хранения перечислимых типов) : в режиме совместимости с Дельфи и ТП по умолчанию принимается {$PACKENUM 1}, в режиме MacPas - {$PACKENUM 2}, в остальных режимах - 4 байта...

Да, максимально теперь поддерживается 232 элементов перечисления (значения хранятся как Byte/Word/Longword в зависимости от количества элементов, и от установленного значения PACKENUM, об этом можно почитать в файле prog.pdf: "8.2.4 Enumeration types")

Цитата
Интервальный тип округляется к большему целому кол-ву байт, но не больше 8ми?
Угу. Ибо самый емкий целочисленный тип имеет размер в 8 байт (Int64 или QWord), больше нет смысла выделять под интервал, границы интервала всегда целочисленные (емкость всех остальных перечислимых типов типов все равно меньше, так что их здесь не принимаем во внимание)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 26.04.2024 7:11
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name