what does | 0x01 do in C language? - c

I have seen something like this in some of my coworkers code today :
I2C1ADB1= (slave_read_address | 0x01);
What does this | 0x01 part do? Does it end 1 at the end of the bits?
Let's say I2C1ADB1=0b00000000. If I use above line, will the new I2C1ADB1 be 0b000000001? Will it also increase the bit count from 8 to 9?

'|' is bit-wise OR operator in C. It does bit-wise OR between two values and return the final value.
I2C1ADB1= (slave_read_address | 0x01);
Assume slave_read_address in binary is 0bxxxxxxxx where each x is bit value 1 or 0. Similarly, 0x01 in binary is 0x00000001.
As you know OR will return true (1) if at least one of the value is true (1). Otherwise returns false (0).
So After the above C line, I2C1ADB1 will have 0bxxxxxxx1.
The operator will not ADD bits. Usually '|' (OR) operator is used to set a particular set of bits without altering other bits.

The statement I2C1ADB1 = (slave_read_address | 0x01); stores the value of slave_read_address into I2C1ADB1, forcing the low order bit to 1.
Your interpretation is incorrect, the value is not shifted, no extra bit is appended. The lowest bit is set to 1:
0 becomes 1,
1 is unchanged,
2 becomes 3,
3 does not change,
4 becomes 5,
etc.

Because on the left you have a variable and on the right a constant the result is to set all the corresponding 1 bits from the constant in the variable. In this case you’re right: it sets the last bit. No bit count increase occur!

Related

Error during SqlBulkCopy WriteToServer - Message (Incorrect syntax near 'ALLOW_ENCRYPTED_VALUE_MODIFICATIONS'.))

I was trying to upload the data from my datatable using SqlBulkCopy. But after the line goes to WriteToServer(dt) the system returns an exception
Incorrect syntax near 'ALLOW_ENCRYPTED_VALUE_MODIFICATIONS'
I've already tried adding sqlBulkCopyOptions but the error is still the same.
Dim mapSessionNo As New SqlBulkCopyColumnMapping, mapBatchID As New SqlBulkCopyColumnMapping, mapPolicyID As New SqlBulkCopyColumnMapping, mapUpdateDts As New SqlBulkCopyColumnMapping, mapID As New SqlBulkCopyColumnMapping
Dim bulkcopy As SqlBulkCopy = New SqlBulkCopy(ConnectionString, SqlBulkCopyOptions.FireTriggers & SqlBulkCopyOptions.CheckConstraints & SqlBulkCopyOptions.KeepIdentity & SqlBulkCopyOptions.UseInternalTransaction)
bulkcopy.DestinationTableName = "BatchUpdateLog"
mapSessionNo = New SqlBulkCopyColumnMapping("SessionNo", "SessionNo")
mapBatchID = New SqlBulkCopyColumnMapping("BatchID", "BatchID")
mapPolicyID = New SqlBulkCopyColumnMapping("PolicyID", "PolicyID")
mapUpdateDts = New SqlBulkCopyColumnMapping("UpdateDts", "UpdateDts")
mapID = New SqlBulkCopyColumnMapping("ID", "ID")
bulkcopy.NotifyAfter = 10000
bulkcopy.ColumnMappings.Add(mapID)
bulkcopy.ColumnMappings.Add(mapSessionNo)
bulkcopy.ColumnMappings.Add(mapBatchID)
bulkcopy.ColumnMappings.Add(mapPolicyID)
bulkcopy.ColumnMappings.Add(mapUpdateDts)
bulkcopy.WriteToServer(dt)
bulkcopy.Close()
I expect the whole data table will be uploaded to the database. But the system returns an error when it comes to the WriteToServer line of code
I suspect that the issue is that here:
Dim bulkcopy As SqlBulkCopy = New SqlBulkCopy(ConnectionString, SqlBulkCopyOptions.FireTriggers & SqlBulkCopyOptions.CheckConstraints & SqlBulkCopyOptions.KeepIdentity & SqlBulkCopyOptions.UseInternalTransaction)
you are performing string concatenation on the SqlBulkCopyOptions values instead of combination. You combine Enum values with a bitwise Or. I suspect that you were going for a bitwise And, which would still be wrong. In C#, the & operator is a bitwise And but it's string concatenation in VB. That should be:
Dim bulkcopy As SqlBulkCopy = New SqlBulkCopy(ConnectionString, SqlBulkCopyOptions.FireTriggers Or SqlBulkCopyOptions.CheckConstraints Or SqlBulkCopyOptions.KeepIdentity Or SqlBulkCopyOptions.UseInternalTransaction)
EDIT: It's a bit counter-intuitive that you need to use Or when, logically, you want one value AND another value. It's perfectly logical if you understand bitwise logic though. Bitwise logic is basically Boolean logic on the individual bits of a numeric value. Let's say that you have two Enum values where one has the numeric value 4 and the other has the value 32. In binary, those two values would look like this:
0000 0100
0010 0000
Bitwise operations work on corresponding pairs of bits and treat 1 as TRUE and 0 as FALSE. In Boolean logic, the result of an OR operation is TRUE if either operand is TRUE, otherwise it is FALSE. That means that, in bitwise operations, a bit in the result will be 1 if either of the corresponding bits in the operands is 1, otherwise it will be 0. That means that the result of a bitwise OR on those two values will have a 1 anywhere either operand has a 1 and a 0 everywhere else:
0010 0100
If you did a bitwise AND then the result would only have a 1 where both operands had a 1 and 0 everywhere else. Those two operands don't both have a 1 anywhere so the result would be all 0:
0000 0000
When it comes to Enums, you use bitwise OR to combine, bitwise AND to mask, bitwise AND NOT to test and bitwise XOR to toggle. By "mask" I mean remove all but certain values. For instance, let's say that you have an unknown combination of the same Enum as before and you want to mask out all but the 4 and 32 values. You would first combine 4 and 32 with a bitwise OR and then AND that with your current value. The result of a bitwise AND will have a 1 where both operands have a 1, so it can only have a 1 in the 4 or 32 position but it will only have a 1 in those positions if the original value does, e.g. if the original value was:
1010 1010
and we AND it with:
0010 0100
then we get:
0010 0000
Hopefully this helps a bit with bitwise logic.
have you tried SqlBulkCopyOptions.Default?
or what about the ALLOW_ENCRYPTED_VALUE_MODIFICATIONS user property? https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-user-transact-sql?view=sql-server-2017
Cheers

Switching the bits

How can I switch the certain bits of a number? For example, given bit representation (just an example, the syntax is surely wrong!):
someNumber = 00110111
changeNumber = 11100110
Then how can I change the far right bit of someNumber with the far right bit of the changeNumber without changing the rest bits of the someNumber? So the result would be:
00110111 //someNumber
11100110 //changeNumber
________
00110110
Extract the far right bit of changeNumber:
changeNumber & 1
Remove the far right bit of someNumber:
someNumber & ~1
And OR them together:
(changeNumber & 1) | (someNumber & ~1)
To set bit n, change 1 to 2n.
One a similar line as Martin,
Test the last bit of someNumber, and use the result to select the operation to change some number ('bitwise and' or 'bitwise or')
#DEFINE SWITCH_MASK_OR 0b00000001
#DEFINE SWITCH_MASK_AND (~SWITCH_MASK_OR)
...
result = changeNumber & SWITCH_MASK_OR ? \
someNumber | SWITCH_MASK_OR : someNumber & SWITCH_MASK_AND;
I suggest the following steps:
Clear the last bit of someNumber.
someNumber &= ~1
Extract the last bit of changeNumber
int lastBit = changeNumber & 1;
Set the last bit of someNumber:
someNumber |= lastBit;
AND the changenumber with a mask of 00000001, so extracting the state of the lowest bit, all others set to 0: 00000000
AND the somenumber with a mask of 11111110, so setting the lowest bit to 0 while leaving the rest unchanged: 00110110
OR the two results together, so : 00110110

Check last bit in a hex in SQL

I have a SQL entry that is of type hex (varbinary) and I want to do a SELECT COUNT for all the entries that have this hex value ending in 1.
I was thinking about using CONVERT to make my hex into a char and then use WHERE my_string LIKE "%1". The thing is that varchar is capped at 8000 chars, and my hex is longer than that.
What options do I have?
Varbinary actually works with some string manipulation functions, most notably substring. So you can use eg.:
select substring(yourBinary, 1, 1);
To get the first byte of your binary column. To get the last bit then, you can use this:
select substring(yourBinary, len(yourBinary), 1) & 1;
This will give you zero if the bit is off, or one if it is on.
However, if you really only have to check at most the last 4-8 bytes, you can easily use the bitwise operators on the column directly:
select yourBinary & 1;
As a final note, this is going to be rather slow. So if you plan on doing this often, on large amounts of data, it might be better to simply create another bit column just for that, which you can index. If you're talking about at most a thousand rows or so, or if you don't care about speed, fire away :)
Check last four bits = 0001
SELECT SUM(CASE WHEN MyColumn % 16 IN (-15,1) THEN 1 END) FROM MyTable
Check last bit = 1
SELECT SUM(CASE WHEN MyColumn % 2 IN (-1,1) THEN 1 END) FROM MyTable
If you are wondering why you have to check for negative moduli, try SELECT 0x80000001 % 16
Try using this where
WHERE LEFT(my_string,1) = 1
It it's text values ending in 1 then you want the Right as opposed to the Left
WHERE RIGHT(my_string,1) = 1

Serial data parsing

I have a probably simple question, which I just cant seem to understand.
I am creating a serial parser for a datalogger which sends a serial stream. Under the documentation for the product a calculation is stated, which I don't understand.
Lateral = Data1 And 0x7F + Data2 / 0x100
If (Data1 And 0x80)=0 Then Lateral = -Lateral
What does Data1 And 0x7f means? I know that 7F is 127, but besides that I don't understand the combination with the And statement.
What would the real formula look like?
Bitwise AND -- a bit in the output is set if and only if the corresponding bit is set in both inputs.
Since your tags indicate that you're working in C, you can perform bitwise AND with the & operator.
(Note that 0x7F is 01111111 and 0x80 is 10000000 in binary, so ANDing with these correspond respectively to extracting the lower seven bits and extracting the upper bit of a byte.)
1st sentence
Lateral = Data1 And(&) 0x7f + Data2/ 0x100
means take the magnitude of Data1(Data and 0x7f) and add to it the value of Data2/256
2nd sentence
check the sign od Data1 and assign the same to Lateral.

Ampersand (&) operator in a SQL Server WHERE Clause

Sorry for the very basic question. What does the & operator do in this SQL
WHERE (sc.Attributes & 1) = 0
sc is an alias for a table which contains a column attributes.
I'm trying to understand some SQL in a report and that line is making it return 0 entries. If I comment it out it works. I have limited SQL knowledge and I'm not sure what the & 1 is doing.
& is the bitwise logical and operator - It performs the operation on 2 integer values.
WHERE (sc.Attributes & 1) = 0
The above code checks to see if sc.Attributes is an even number. Which is the same as saying that the first bit is not set.
Because of the name of the column though: "Attributes", then the "1" value is probably just some flag that has some external meaning.
It is common to use 1 binary digit for each flag stored in a number for attributes. So to test for the first bit you use sc.Attributes&1, to test for the second you use sc.Attributes&2, to test for the third you use sc.Attributes&4, to test for the fourth you use sc.Attributes&8, ...
The = 0 part is testing to see if the first bit is NOT set.
Some binary examples: (== to show the result of the operation)
//Check if the first bit is set, same as sc.Attributes&1
11111111 & 00000001 == 1
11111110 & 00000001 == 0
00000001 & 00000001 == 1
//Check if the third bit is set, same as sc.Attributes&4
11111111 & 00000100 == 1
11111011 & 00000100 == 0
00000100 & 00000100 == 1
It is a bitwise logical AND operator.
It's a bitwise and.
Seeing as you tagged this as sql server, I thought I'd add something from a different angle as also ran into one of these this week.
These can hurt the performance of your queries if used in the predicate. Very easy to manufacture an example of your own. Here is the snippet from my query
WHERE
advertiserid = #advertiserid
AND (is_deleted & #dirty > 0)
WHERE
advertiserid = #advertiserid
AND (is_deleted > 0 AND #dirty > 0)
by simply defining each column with a proper value this allowed the optimizer to remove a bookmark lookup and performance stats showed a X10 performance increase.

Resources