Добавлен , опубликован
Внимание! Запись предназначена для тех, кто знает или изучает язык программирования C#.
Что-то давно ничего не писал на C#, а сегодня вдруг решил проверить одну свою старую идею.
Логический тип данных или bool вы, конечно, не раз использовали в коде. Ну, если не просто так зашли сюда =)
Однажды меня заинтересовала одна его особенность и я попробовал применить её, из чего и вышла эта запись.
Особенность в том, что в bool используется один бит. Конечно, в памяти, в виде одного бита он не будет храниться. Поэтому в памяти он занимает больше места.
Эти биты нигде не используются (исключение - когда 0 станет не 0 false станет true, поэтому сюрпризы приделываются только к true), поэтому на первый взгляд bool не изменится, если мы в них запишем что-нибудь. Однако в себе он будет хранить дополнительную информацию.
Перейдём к практическому решению.
Код очень простой! Но присутствует unsafe.
static bool ByteToBool(byte bt)
{
	bool* p = (bool*)&bt;
	bool b = *p;
	return b;
	//Можно было и одной строчкой, но так понятнее.
}
В этом простейшем методе мы получаем доступ к тому одному байту, в котором наше значение. Почему не int? Проверено мной, при копировании bool копируется только последний байт.
И туда мы пишем любое число от 0 до 255. Если оно равно 0 - false, не равно - true.
static byte BoolToByte(bool b)
{
	byte* p = (byte*)&b;
	byte bt = *p;
	return bt;
}
А это - обратное действие. Мы получаем то число, которое записали. Остаётся проверить всё это на практике. Вывод написал в комментарии, как и пояснения.
static void Main(string[] args)
{
	bool b = ByteToBool(111);//bool с сюрпризом
	Console.WriteLine(b);//True. 
	if (b)
	{ Console.WriteLine(b); }//True. Работает в условиях.

	//Теперь попробуем скопировать значение
	bool b1 = b;
	byte bt = BoolToByte(b1);//111. Сохранилось.
	Console.WriteLine(bt);

	//И ещё любопытное.
	Console.WriteLine(b1 == true);
	//True. Сравнивается только последний бит.

	Console.ReadLine();//Чтобы мы успели прочитать =)
}
Вот так вот.
Примечание №1.
В результате отладки выяснил, что с false такого всё-таки не выйдет - проверяется на 0 весь. Но зато true можно сделать много вариантов.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
29
9 лет назад
0
Ничего нового, да и собственно зачем это? не понятно...
А вот сделать альтернативное хранилище булов, которые реально будут использовать 1 бид это уже что-то более важное
0
24
9 лет назад
0
Ну, для подобного есть enum flags.
0
9
9 лет назад
Отредактирован AsagiriGen
0
Isstrebitel:
И туда мы пишем любое число от 0 до 255. Если оно равно 0 - false, не равно - true.
Не конкретный бит определяет значение true или false? Не верю. Что покажет при числе 4?
0
24
9 лет назад
Отредактирован Isstrebitel
0
раскрыть
GeneralElConsul, нет. В памяти в NET большинство переменных, даже маленьких, будут по 4 байта.
Но первые 3 для bool не используются, при копировании переменной они даже не копируются. А последний байт копируется. И он никуда не пропадёт.
На второе сейчас напишу.
0
29
9 лет назад
0
0
24
9 лет назад
0
GeneralElConsul, это ещё в C была такая логика - 0 - false, остальное - true. В C#, похоже, тоже, проверяет не конкретный бит, а, как в C, всё число.
0
9
9 лет назад
Отредактирован AsagiriGen
0
GeneralElConsul, нет. В памяти в NET большинство переменных, даже маленьких, будут по 4 байта.
Но первые 3 для bool не используются, при копировании переменной они даже не копируются. А последний байт копируется. И он никуда не пропадёт.
Да, это уже вспомнил про типы в стеке вычислений.
Isstrebitel:
GeneralElConsul, это ещё в C была такая логика - 0 - false, остальное - true. В C#, похоже, тоже, проверяет не конкретный бит, а, как в C, всё число.
Ок, буду знать.
0
24
9 лет назад
Отредактирован Isstrebitel
0
Я сначала сам во время отладки подозревал, что как-то по другому, раз обычно больше 2 значений не предусмотрено. Но нет - также.
А проверка на 0 - она с точки зрения машинного кода довольно простая.
Скачал MASM - узнал.
0
29
9 лет назад
0
Isstrebitel, буленовские проверки там делаются проверкой 1 флага процессора ZF (Zero Flag), который обновляется после любой арифметической операции
0
24
9 лет назад
0
alexprey, я как раз об этом. Специально проверять во многих случаях не надо.
0
29
9 лет назад
0
nvc123,
Isstrebitel, c# намного ближе к c++ чем java
Это с какой это стороны?
alexprey, подобные альтернативные хранилища уже придуманы, см. protobuf
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.