C
C#ā€¢2y ago
Hannsen

ā” Determine if bit within a decimal value is set or not

Hi, i have property of type decimal . - I want to iterate bit 0 - 63 and check if the bit is actually set in the decimal value or not. Anyone have an idea how i can do this? - With datatype int, it ain't a problem but getting such an info out of a large decimal (I allow only integers) number, i have no clue šŸ˜¦
62 Replies
ero
eroā€¢2y ago
for (int i = 0; i < 64; i++)
{
bool bitIsSet = (value & (1 << i)) != 0;
}
for (int i = 0; i < 64; i++)
{
bool bitIsSet = (value & (1 << i)) != 0;
}
?
Hannsen
HannsenOPā€¢2y ago
Thank you Ero
mtreit
mtreitā€¢2y ago
How do you usually do this for int?
Hannsen
HannsenOPā€¢2y ago
@mtreit šŸ™‚ The same way as above. - But i have to say, i went down from decimal to long, because with decimal this provided solution does not work. (value & (1 << i)) != 0 This actually does not work, if "value" is of datatype decimal. Application should demonstrate bits changing visually.
Hannsen
HannsenOPā€¢2y ago
Hannsen
HannsenOPā€¢2y ago
First i tried to support 64 bit visualisation. - But i went down to max 32 bit visualisation. This should already fulfill the purpose of demonstrating bits and bytes. If you have a solution, which actually covers real 64 bits , then please let me know. - Funny thing is with the solution of Ero, if i enter "3" bit 0 and 1 are set, but also 33 and 34.
mtreit
mtreitā€¢2y ago
Do you have an example of what you mean?
Hannsen
HannsenOPā€¢2y ago
Give me a bit, i try to provide one
mtreit
mtreitā€¢2y ago
Note that decimal is 128 bits. If you are starting with a decimal you can use decimal.GetBits() to get the four integer values that make up the underlying number (and from there you can look at the actual bit patterns if desired.)
Hannsen
HannsenOPā€¢2y ago
Good idea, so it should be enough to decimal.GetBits() look at [0] and [1] for the 64 bits. - I will give it a shot
mtreit
mtreitā€¢2y ago
Look here to make sure you understand the underlying structure of a decimal number, if that's important for your use case: https://learn.microsoft.com/en-us/dotnet/api/system.decimal.getbits?view=net-7.0
Decimal.GetBits Method (System)
Converts the value of a specified instance of Decimal to its equivalent binary representation.
mtreit
mtreitā€¢2y ago
Specifically:
The first, second, and third elements of the returned array contain the low, middle, and high 32 bits of the 96-bit integer number. The fourth element of the returned array contains the scale factor and sign. It consists of the following parts: Bits 0 to 15, the lower word, are unused and must be zero. Bits 16 to 23 must contain an exponent between 0 and 28, which indicates the power of 10 to divide the integer number. Bits 24 to 30 are unused and must be zero. Bit 31 contains the sign: 0 mean positive, and 1 means negative.
Hannsen
HannsenOPā€¢2y ago
Interesting. - Of course there must be something like a "pattern" change when i compare with 8 bit šŸ™‚ Thank you for letting me know
ero
eroā€¢2y ago
just cast to ulong?
Hannsen
HannsenOPā€¢2y ago
ero
eroā€¢2y ago
so cast the other one to ulong too...
Hannsen
HannsenOPā€¢2y ago
1, i and 0 ?
ero
eroā€¢2y ago
(ulong)(1 << i) the other side of the operation, of course
Hannsen
HannsenOPā€¢2y ago
Ok, that seems to function, thanks But why do i have the following problem:
for (int i = 0; i < AmountOfBit.SelectedValue; i++)
{
// Check if bit i is set
if (((ulong)decimalValue & (ulong)(1 << i)) != 0)
{
// Bit is set
System.Diagnostics.Debug.WriteLine($"Bit {i} is set");
Bits.Where(b => b.Bit == i).FirstOrDefault().BitValue = true;
}
else
{
// Bit is not set
System.Diagnostics.Debug.WriteLine($"Bit {i} is not set");
Bits.Where(b => b.Bit == i).FirstOrDefault().BitValue = false;
}
}
for (int i = 0; i < AmountOfBit.SelectedValue; i++)
{
// Check if bit i is set
if (((ulong)decimalValue & (ulong)(1 << i)) != 0)
{
// Bit is set
System.Diagnostics.Debug.WriteLine($"Bit {i} is set");
Bits.Where(b => b.Bit == i).FirstOrDefault().BitValue = true;
}
else
{
// Bit is not set
System.Diagnostics.Debug.WriteLine($"Bit {i} is not set");
Bits.Where(b => b.Bit == i).FirstOrDefault().BitValue = false;
}
}
Hannsen
HannsenOPā€¢2y ago
Hannsen
HannsenOPā€¢2y ago
Bit 0 is set Bit 1 is set Bit 2 is not set Bit 3 is not set Bit 4 is not set Bit 5 is not set Bit 6 is not set Bit 7 is not set Bit 8 is not set Bit 9 is not set Bit 10 is not set Bit 11 is not set Bit 12 is not set Bit 13 is not set Bit 14 is not set Bit 15 is not set Bit 16 is not set Bit 17 is not set Bit 18 is not set Bit 19 is not set Bit 20 is not set Bit 21 is not set Bit 22 is not set Bit 23 is not set Bit 24 is not set Bit 25 is not set Bit 26 is not set Bit 27 is not set Bit 28 is not set Bit 29 is not set Bit 30 is not set Bit 31 is not set Bit 32 is set Bit 33 is set Bit 34 is not set Bit 35 is not set Bit 36 is not set Bit 37 is not set If i enter 3, it says bit 1 and 2 is set, but also bit 32 and 33
ero
eroā€¢2y ago
ah, wait... decimal is 128 bits i just remembered
Hannsen
HannsenOPā€¢2y ago
But i am using long in that sample
ero
eroā€¢2y ago
decimalValue is of type long?
Hannsen
HannsenOPā€¢2y ago
Variable is just called "decimalValue"
Hannsen
HannsenOPā€¢2y ago
Hannsen
HannsenOPā€¢2y ago
I pass datatype long, yes.
ero
eroā€¢2y ago
can't repro
MODiX
MODiXā€¢2y ago
Ero#1111
REPL Result: Success
long foo = 3;

for (int i = 0; i < 64; i++)
{
bool set = ((ulong)foo & (ulong)(1 << i)) != 0;
Console.WriteLine($"Bit {i} is {(set ? "set" : "not set")}");
}
long foo = 3;

for (int i = 0; i < 64; i++)
{
bool set = ((ulong)foo & (ulong)(1 << i)) != 0;
Console.WriteLine($"Bit {i} is {(set ? "set" : "not set")}");
}
Console Output
Bit 0 is set
Bit 1 is set
Bit 2 is not set
Bit 3 is not set
Bit 4 is not set
Bit 5 is not set
Bit 6 is not set
Bit 7 is not set
Bit 8 is not set
Bit 9 is not set
Bit 10 is not set
Bit 11 is not set
Bit 12 is not set
Bit 13 is not set
Bit 14 is not set
Bit 15 is not set
Bit 16 is not set
Bit 17 is not set
Bit 18 is not set
Bit 19 is not set
Bit 20 is not set
Bit 21 is not set
Bit 22 is not set
Bit 23 is not set
Bit 24 is not set
Bit 25 is not set
Bit 26 is not set
Bit 27 is not set
Bit 28 is not set
Bit 29 is not set
Bit 30 is not set
Bit 31 is not set
Bit 32 is set
Bit 33 is set
Bit 34 is not set
Bit 35 is not set
Bit 36 is not set
Bit 37 is not set
Bit 38 is not set
Bit 39 is not set
Bit 40 is not set
Bit 41 is not set
Bit 42 is not set
Bit 43 is not set
Bit 44 is not set
Bit 45 is not set
Bit 46 is not set
Bit 47 is not set
Bit 48 is not set
Bit 49 is not set
Bit 50 is not set
Bit 51 is not set
Bit 52 is not set
Bit 53 is not set
Bit 54 is not set
Bit 55 is not set
Bit 56 is not set
Bit 0 is set
Bit 1 is set
Bit 2 is not set
Bit 3 is not set
Bit 4 is not set
Bit 5 is not set
Bit 6 is not set
Bit 7 is not set
Bit 8 is not set
Bit 9 is not set
Bit 10 is not set
Bit 11 is not set
Bit 12 is not set
Bit 13 is not set
Bit 14 is not set
Bit 15 is not set
Bit 16 is not set
Bit 17 is not set
Bit 18 is not set
Bit 19 is not set
Bit 20 is not set
Bit 21 is not set
Bit 22 is not set
Bit 23 is not set
Bit 24 is not set
Bit 25 is not set
Bit 26 is not set
Bit 27 is not set
Bit 28 is not set
Bit 29 is not set
Bit 30 is not set
Bit 31 is not set
Bit 32 is set
Bit 33 is set
Bit 34 is not set
Bit 35 is not set
Bit 36 is not set
Bit 37 is not set
Bit 38 is not set
Bit 39 is not set
Bit 40 is not set
Bit 41 is not set
Bit 42 is not set
Bit 43 is not set
Bit 44 is not set
Bit 45 is not set
Bit 46 is not set
Bit 47 is not set
Bit 48 is not set
Bit 49 is not set
Bit 50 is not set
Bit 51 is not set
Bit 52 is not set
Bit 53 is not set
Bit 54 is not set
Bit 55 is not set
Bit 56 is not set
Compile: 630.915ms | Execution: 97.624ms | React with āŒ to remove this embed.
ero
eroā€¢2y ago
WhatChamp
Hannsen
HannsenOPā€¢2y ago
But you did repro it. - I am confused...
ero
eroā€¢2y ago
it has to be something obvious
Hannsen
HannsenOPā€¢2y ago
@mtreit Any ideas?
ero
eroā€¢2y ago
oh it's yeah
Hannsen
HannsenOPā€¢2y ago
pastes popcorn eating meme
ero
eroā€¢2y ago
1 << i is bit shifting an int and then casting it to a ulong which obviously overflows if i is > 31
MODiX
MODiXā€¢2y ago
Ero#1111
REPL Result: Success
long foo = 3;

for (int i = 0; i < 64; i++)
{
bool set = ((ulong)foo & (1UL << i)) != 0;
Console.WriteLine($"Bit {i} is {(set ? "set" : "not set")}");
}
long foo = 3;

for (int i = 0; i < 64; i++)
{
bool set = ((ulong)foo & (1UL << i)) != 0;
Console.WriteLine($"Bit {i} is {(set ? "set" : "not set")}");
}
Console Output
Bit 0 is set
Bit 1 is set
Bit 2 is not set
Bit 3 is not set
Bit 4 is not set
Bit 5 is not set
Bit 6 is not set
Bit 7 is not set
Bit 8 is not set
Bit 9 is not set
Bit 10 is not set
Bit 11 is not set
Bit 12 is not set
Bit 13 is not set
Bit 14 is not set
Bit 15 is not set
Bit 16 is not set
Bit 17 is not set
Bit 18 is not set
Bit 19 is not set
Bit 20 is not set
Bit 21 is not set
Bit 22 is not set
Bit 23 is not set
Bit 24 is not set
Bit 25 is not set
Bit 26 is not set
Bit 27 is not set
Bit 28 is not set
Bit 29 is not set
Bit 30 is not set
Bit 31 is not set
Bit 32 is not set
Bit 33 is not set
Bit 34 is not set
Bit 35 is not set
Bit 36 is not set
Bit 37 is not set
Bit 38 is not set
Bit 39 is not set
Bit 40 is not set
Bit 41 is not set
Bit 42 is not set
Bit 43 is not set
Bit 44 is not set
Bit 45 is not set
Bit 46 is not set
Bit 47 is not set
Bit 48 is not set
Bit 49 is not set
Bit 50 is not set
Bit 51 is not set
Bit 52 is not set
Bit 53 is not set
Bit 54 is not set
Bit 55 is not set
Bit 56 is
Bit 0 is set
Bit 1 is set
Bit 2 is not set
Bit 3 is not set
Bit 4 is not set
Bit 5 is not set
Bit 6 is not set
Bit 7 is not set
Bit 8 is not set
Bit 9 is not set
Bit 10 is not set
Bit 11 is not set
Bit 12 is not set
Bit 13 is not set
Bit 14 is not set
Bit 15 is not set
Bit 16 is not set
Bit 17 is not set
Bit 18 is not set
Bit 19 is not set
Bit 20 is not set
Bit 21 is not set
Bit 22 is not set
Bit 23 is not set
Bit 24 is not set
Bit 25 is not set
Bit 26 is not set
Bit 27 is not set
Bit 28 is not set
Bit 29 is not set
Bit 30 is not set
Bit 31 is not set
Bit 32 is not set
Bit 33 is not set
Bit 34 is not set
Bit 35 is not set
Bit 36 is not set
Bit 37 is not set
Bit 38 is not set
Bit 39 is not set
Bit 40 is not set
Bit 41 is not set
Bit 42 is not set
Bit 43 is not set
Bit 44 is not set
Bit 45 is not set
Bit 46 is not set
Bit 47 is not set
Bit 48 is not set
Bit 49 is not set
Bit 50 is not set
Bit 51 is not set
Bit 52 is not set
Bit 53 is not set
Bit 54 is not set
Bit 55 is not set
Bit 56 is
Compile: 686.824ms | Execution: 98.335ms | React with āŒ to remove this embed.
ero
eroā€¢2y ago
so you need to make 1 a ulong, and only then shift it so it doesn't overflow
Hannsen
HannsenOPā€¢2y ago
You are my hero.
ero
eroā€¢2y ago
and if you wanna get this to work with decimal, you probably need to use UInt128 ((UInt128)value & (UInt128.One << i))
Hannsen
HannsenOPā€¢2y ago
At the end, i wanna show the dec value of all bits set. - UInt64 should be able to have a value of all 64 bits set right? (Am using positive only)
ero
eroā€¢2y ago
sure, but decimal is not just 64 bits if you restrict the input to double, then sure
mtreit
mtreitā€¢2y ago
I was just going to point out that the mask needs to be unsigned. I wrote it like this:
ulong foo = 3;
uint mask = 1U;

for (int i = 0; i < 64; i++)
{
bool set = (foo & mask) != 0;
Console.WriteLine($"Bit {i} is {(set ? "set" : "not set")}");
mask <<= 1;
}
ulong foo = 3;
uint mask = 1U;

for (int i = 0; i < 64; i++)
{
bool set = (foo & mask) != 0;
Console.WriteLine($"Bit {i} is {(set ? "set" : "not set")}");
mask <<= 1;
}
Hannsen
HannsenOPā€¢2y ago
Plan is now, that i go for ulong, since its the max i need then
ero
eroā€¢2y ago
i mean long quite literally is not a decimal number
Hannsen
HannsenOPā€¢2y ago
Yep true, o cover this
mtreit
mtreitā€¢2y ago
"Decimal" in C# is a very different thing than integers (int, long, uint, ulong), when you use the term "dec value" are you really talking about the special decimal type that can represent fractional numbers with more precision than floating point?
Hannsen
HannsenOPā€¢2y ago
Hannsen
HannsenOPā€¢2y ago
Regex is keeping input valid.
ero
eroā€¢2y ago
those look very strange...
Hannsen
HannsenOPā€¢2y ago
True, i just want to support non-fratctional numbers, just 0 and positive "Integer" numbers
ero
eroā€¢2y ago
i don't think range does what you think it does there you specify MaxLength(19), but the regex allows 20...
mtreit
mtreitā€¢2y ago
In that case, don't use the term "decimal" as it confuses everything. Use the term "integer".
Hannsen
HannsenOPā€¢2y ago
DEC would be correct i guess, since windows calculator does it that way too šŸ™‚
ero
eroā€¢2y ago
oh. oh yeah do not do that
Hannsen
HannsenOPā€¢2y ago
Just a sample, Attritube, will be reworked. - Was from some testing It does not look that bad, when i compare it with the windows calculator.
Hannsen
HannsenOPā€¢2y ago
Hannsen
HannsenOPā€¢2y ago
@mtreit Question i ask myself, since i read the MS documentation link you posted. - Am i lying? - Is the official windows calculator lying? As stated in the docs, from some point onwards of bits, they need to be interpreted differently. Bits on a certain level, seems to have a different meaning depending on the datatype someone is actually using.
Hannsen
HannsenOPā€¢2y ago
Hohoho, official WIN11 calculator seems to be bugged. - If i set all bits there, i get the following output:
Hannsen
HannsenOPā€¢2y ago
LOL, might be, because the actual datatype which stores the DEC value is to small, it does not fit its value and overflows.
mtreit
mtreitā€¢2y ago
-1 is the correct interpretation of all one bits for signed values. You are mixing signed (can be negative) and unsigned (cannot be negative) it sounds like.
Accord
Accordā€¢2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server