C# How convert short[] to bool[]?
Asked Answered
C

3

8
short[] sBuf = new short[2];
sBuf[0] = 1;
sBuf[1] = 2;

bool[] bBuf = new bool[sBuf.Length * 16];
Buffer.BlockCopy(sBuf, 0, bBuf, 0, sBuf.Length * 2);

Desired result value  
sBuf[0] = 1
bBuf[0] = true, bBuf[1] = false, bBuf[2] = false, bBuf[3] = false...
sBuf[0] = 2
bBuf[16] = false, bBuf[17] = true, bBuf[18] = false, bBuf[19] = false...

But can not be converted correctly.
I want to convert from short [] to bool [], but I don't know how.

Charlton answered 6/4, 2017 at 11:26 Comment(3)
When should the bool element be true?Bedpost
@cat: a question to save me some brain cycles :)Bedpost
@cat So you want to turn -1, one of the two commonly used values for true, into false? It's good to ask the question and let the OP decide. And based on dasblinkenlight's accepted answer, your guess would have been as wrong as my guess.Aday
L
14

Assuming that each bool represents a bit from its corresponding short (which is presumably why you multiplied the size by 16) you can do the conversion as follows:

bBuf = sBuf
    .SelectMany(s => Enumerable.Range(0, 16).Select(i => (s & (1<<i)) != 0))
    .ToArray();

The idea is to construct 16 booleans for each short by calling Enumerable.Range, masking the number with (1 << i), and comparing the result to zero.

Lengel answered 6/4, 2017 at 11:30 Comment(9)
Build errors occur. CS0019 '&' Operator cannot be applied to operands of type 'short' and 'bool'Charlton
@Charlton I edited the answer after you copied the code. A pair of parentheses was missing. Please try again.Lengel
@Charlton you should use updated answer with brackets around s & (1<<i) actually you can remove inner brackets: i => (s & 1 << i ) != 0 but it's not that readableOrnas
@dasblinkenlight Resolved. Thank you for your reply.Charlton
Nice approach. You can optimize it a little bit by taking out of SelectMany the call to Enumerable.Range(0, 16) and store it in a variable.Forerunner
@fubo dasblinkenlight's answer seems consistent with OP example, even if the question is unclear.Forerunner
I'm still not convinced LINQ isn't magic. That said, maybe it's just me but I find this really hard to read.Tomikotomkiel
@dasblinkenlight Could you help me understand (s & (1<<i)) better? I very rarely see & instead of &&. Additionally, while I read MSDN on the << operator I also don't entirely "get" itTomikotomkiel
@Tomikotomkiel Please see this Q&A, it explains how to check if a bit at position b is set or not.Lengel
R
4

From msdn page of Convert.ToBoolean it says that every 0 value will be converted to false and every non-0 value to true :

bool[] bBuf = new bool[sBuf.Length];
for(int i = 0; i < sBuf.Length; ++i )
{
    bBuf[i] = Convert.ToBoolean(sBuf[i]);
}

EDIT :
Setting your bool[] based on bits set in short value you can use this :

const int BITS_PER_BYTE = 8; // amount of bits per one byte

int elementBitsSize = sizeof(short) * BITS_PER_BYTE; // size in bits of one element in array
bool[] bBuf = new bool[sBuf.Length * elementBitsSize]; // new array size

// iterate through each short value
for ( int i = 0; i < sBuf.Length; ++i )
{
    // iterate through bits in that value
    for( int j = 0; j < elementBitsSize; ++j )
    {
        // assign new value
        bBuf[j + i * elementBitsSize] = Convert.ToBoolean(sBuf[i] & (1 << j));
    }
}

Working example

Rangoon answered 6/4, 2017 at 11:29 Comment(1)
I like this solution as it is, in my opinion, far easier to read than the Selected Answer's LINQ solution. That said, this wouldn't work for OP. For the explicit task of "convert short[] to bool[]" it is fine (though I personally like to always use T.TryParse() unless I can guarantee the integrity of the data) but since OP is dealing with the individual bits of each short to build 16 times more more bool values than he has shorts this isn't what he's actually looking forTomikotomkiel
P
1
// Convert short to bool
bool[] bBuf = Array.ConvertAll(sBuf, n => n != 0);

// Convert short to bit representation bool array
bool[][] bBuf= Array.ConvertAll(arr, n =>
{
    bool[] bits = new bool[16];

    for (int index = 0; index < 16; index++)
    {
        bits[index] = (n & (1 << index)) > 0;
    }

    return bits;
});
Paranoiac answered 6/4, 2017 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.