ā 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
?
Thank you Ero
How do you usually do this for int?
@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.
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.
Do you have an example of what you mean?
Give me a bit, i try to provide one
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.)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
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.
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.
Interesting. - Of course there must be something like a "pattern" change when i compare with 8 bit š
Thank you for letting me know
just cast to
ulong
?so cast the other one to ulong too...
1, i and 0 ?
(ulong)(1 << i)
the other side of the operation, of courseOk, that seems to function, thanks
But why do i have the following problem:
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
ah, wait... decimal is 128 bits
i just remembered
But i am using long in that sample
decimalValue
is of type long
?Variable is just called "decimalValue"
I pass datatype long, yes.
can't repro
Ero#1111
REPL Result: Success
Console Output
More...
Compile: 630.915ms | Execution: 97.624ms | React with ā to remove this embed.
But you did repro it. - I am confused...
it has to be something obvious
@mtreit Any ideas?
oh it's
yeah
pastes popcorn eating meme
1 << i
is bit shifting an int
and then casting it to a ulong
which obviously overflows if i
is > 31Ero#1111
REPL Result: Success
Console Output
More...
Compile: 686.824ms | Execution: 98.335ms | React with ā to remove this embed.
so you need to make
1
a ulong, and only then shift it
so it doesn't overflowYou are my hero.
and if you wanna get this to work with
decimal
, you probably need to use UInt128
((UInt128)value & (UInt128.One << i))
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)
sure, but
decimal
is not just 64 bits
if you restrict the input to double
, then sureI was just going to point out that the mask needs to be unsigned. I wrote it like this:
Plan is now, that i go for ulong, since its the max i need then
i mean
long
quite literally is not a decimal numberYep true, o cover this
"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?
Regex is keeping input valid.
those look very strange...
True, i just want to support non-fratctional numbers, just 0 and positive "Integer" numbers
i don't think range does what you think it does there
you specify
MaxLength(19)
, but the regex allows 20...In that case, don't use the term "decimal" as it confuses everything. Use the term "integer".
DEC would be correct i guess, since windows calculator does it that way too š
oh. oh yeah do not do that
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.
@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.
Hohoho, official WIN11 calculator seems to be bugged. - If i set all bits there, i get the following output:
LOL, might be, because the actual datatype which stores the DEC value is to small, it does not fit its value and overflows.
-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.
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.