Bit functions
Perform bitwise operations on integer values.
Bit functions in ClickHouse operate on various data types, including:
- Unsigned integers:
UInt8
,UInt16
,UInt32
,UInt64
- Signed integers:
Int8
,Int16
,Int32
,Int64
- Floating-point numbers:
Float32
,Float64
Additionally, some bit functions extend their support to String
and FixedString
data types.
Result type and behavior
When you use a bit function, the result is always an integer. The bit length of this result is determined by the maximum bit length of the input arguments. This ensures that the output can accommodate the full range of possible values from the operation.
For example:
- If you perform a bitwise operation on two
UInt8
values, the result will be aUInt8
. - If you operate on a
UInt8
and aUInt32
, the result will be aUInt32
.
It’s important to note that the signedness of the result depends on the input arguments:
- If any of the input arguments is a signed integer, the result will also be signed.
- If all inputs are unsigned, the result will be unsigned.
Handling of floating-point numbers
When bit functions encounter floating-point arguments (Float32
or Float64
), these are automatically converted to Int64
before the operation is performed. This conversion ensures that bitwise operations can be carried out consistently, regardless of the input number type.
ClickHouse function reference
bitAnd
Performs a bitwise AND operation on two numeric values.
Syntax:
Arguments:
a
(numeric): First numeric value.b
(numeric): Second numeric value.
Returns:
The result of the bitwise AND operation. [Integer]
Example:
Result:
In this example, bitAnd
is used to check if a taco has both cheese and lettuce. Assuming the flags are:
- 1 (0001): Has cheese
- 2 (0010): Has lettuce
- 4 (0100): Has salsa
The result 3 means both cheese and lettuce are present, 1 means only cheese, 2 means only lettuce, and 0 means neither.
bitOr
Performs a bitwise OR operation on two numeric values.
Syntax:
Arguments:
a
(numeric): First numeric value.b
(numeric): Second numeric value.
Returns:
The result of the bitwise OR operation. [Integer]
Example:
Result:
In this example, bitOr
combines two sets of taco flags. Assuming the flags are:
- 1 (0001): Has cheese
- 2 (0010): Has lettuce
- 4 (0100): Has salsa
The combined_flags
column shows all toppings present on the taco from both flag sets.
bitXor
Performs a bitwise XOR (exclusive OR) operation on two numeric values.
Syntax:
Arguments:
a
(numeric): First numeric value.b
(numeric): Second numeric value.
Returns:
The result of the bitwise XOR operation. [Integer]
Example:
Result:
In this example, bitXor
is used to identify which toppings have changed. Assuming the flags are:
- 1 (001): Has cheese
- 2 (010): Has lettuce
- 4 (100): Has salsa
The changed_toppings
column shows:
- 6 (110): Lettuce and salsa changed (added or removed)
- 1 (001): Cheese changed (added or removed)
- 0 (000): No changes in toppings
bitNot
Performs a bitwise NOT operation on a numeric value.
Syntax:
Arguments:
a
(numeric): The numeric value to apply the bitwise NOT operation to.
Returns:
The result of the bitwise NOT operation. [Integer]
Example:
Result:
In this example, bitNot
inverts all the bits in taco_flags
. Assuming we’re using 8-bit integers:
- 3 (00000011) becomes -4 (11111100)
- 5 (00000101) becomes -6 (11111010)
- 0 (00000000) becomes -1 (11111111)
This operation could be used to find missing toppings or to toggle all flags at once.
bitShiftLeft
Shifts the binary representation of a value to the left by a specified number of bit positions.
Syntax:
Arguments:
a
(numeric): The value to shift.b
(numeric): The number of positions to shift.
Returns:
The shifted value. [Integer]
Example:
Result:
In this example, bitShiftLeft
is used to quickly calculate doubled and quadrupled prices:
- Shifting left by 1 position multiplies the value by 2
- Shifting left by 2 positions multiplies the value by 4
This operation can be useful for quick price calculations or for working with binary flags.
bitShiftRight
Shifts the binary representation of a value to the right by a specified number of bit positions.
Syntax:
Arguments:
a
(numeric): The value to shift.b
(numeric): The number of positions to shift.
Returns:
The shifted value. [Integer]
Example:
Result:
In this example, bitShiftRight
is used to quickly calculate discounted prices:
- Shifting right by 1 position divides the value by 2 (rounding down)
- Shifting right by 2 positions divides the value by 4 (rounding down)
This operation can be useful for quick price calculations or for working with binary flags. Note that this operation always rounds down, which may not be suitable for all pricing scenarios.
bitRotateLeft
Rotates the bits of a numeric value to the left by a specified number of positions.
Syntax:
Arguments:
a
(numeric): The value to rotate.b
(numeric): The number of positions to rotate.
Returns:
The rotated value. [Integer]
Example:
Result:
In this example, bitRotateLeft
is used to rotate the taco flags. Assuming we’re using 4-bit integers:
- 5 (0101) becomes 10 (1010)
- 3 (0011) becomes 6 (0110)
- 7 (0111) becomes 14 (1110)
This operation can be useful for cycling through different combinations of flags or for certain types of encryption algorithms.
bitRotateRight
Rotates the bits of a numeric value to the right by a specified number of positions.
Syntax:
Arguments:
a
(numeric): The value to rotate.b
(numeric): The number of positions to rotate.
Returns:
The rotated value. [Integer]
Example:
Result:
In this example, bitRotateRight
is used to rotate the taco flags. Assuming we’re using 4-bit integers:
- 5 (0101) becomes 10 (1010)
- 3 (0011) becomes 9 (1001)
- 7 (0111) becomes 11 (1011)
This operation can be useful for cycling through different combinations of flags or for certain types of encryption algorithms. It’s the opposite of bitRotateLeft
.
bitSlice
Returns a substring of bits from a given string, starting at a specified offset and with a specified length.
Syntax:
Arguments:
s
(String or FixedString): The input string.offset
(Integer): The starting bit position (1-based index).length
(Integer): The number of bits to extract.
Returns:
A string containing the extracted bits. [String]
Example:
Result:
In this example, bitSlice
extracts 8 bits (1 byte) starting from the 9th bit of the taco_binary_data
. This could represent extracting a specific flavor code from a binary recipe representation.
The result is padded with zeros on the right if the requested length exceeds the available bits. If the offset is negative, it’s counted from the end of the string.
byteSlice
Returns a substring of bytes from a given string, starting at a specified offset and with a specified length.
Syntax:
Arguments:
s
(String or FixedString): The input string.offset
(Integer): The starting byte position (1-based index).length
(Integer): The number of bytes to extract.
Returns:
A string containing the extracted bytes. [String]
Example:
Result:
In this example, byteSlice
extracts 3 bytes starting from the 2nd byte of the taco_recipe
. This could represent extracting specific ingredients or codes from a recipe string.
This function is similar to the substring
function but operates on a byte level rather than a character level, which can be useful for binary data or when working with multi-byte character encodings.
bitTest
Tests whether a specific bit is set in a given numeric value.
Syntax:
Arguments:
x
(numeric): The value to test.n
(numeric): The bit position to test (0-based index, counting from the least significant bit).
Returns:
1 if the bit is set, 0 otherwise. [UInt8]
Example:
Result:
In this example, bitTest
is used to check individual toppings on each taco:
- Bit 0 (value 1) represents cheese
- Bit 1 (value 2) represents lettuce
- Bit 2 (value 4) represents salsa
The function returns 1
if the topping is present and 0
if it’s not.
bitTestAll
Performs a logical AND
operation on all bits at specified positions in a number.
Syntax:
Arguments:
number
(Integer): The number to test.index1
,index2
, … (Integer): Bit positions to test, starting from 0 (rightmost bit).
Returns:
1
if all specified bits are set to 1,0
otherwise. [UInt8]
Example:
Result:
In this example, bitTestAll
checks if bits 0, 2, and 4 are all set in taco_flags
. The binary representation of the flags is:
- 21: 10101 (has all specified toppings)
- 17: 10001 (missing topping at position 2)
- 31: 11111 (has all toppings)
The function returns 1 for orders 1 and 3, where all specified bits are set, and 0 for order 2, where one bit is not set.
bitTestAny
Returns the result of a logical OR operation on all bits at the specified positions in a number.
Syntax:
Arguments:
number
(Integer): The number to test.index1
,index2
, … (Integer): The bit positions to test. Counting starts from 0, right to left.
Returns:
1
if any of the specified bits are set to 1,0
otherwise. [UInt8]
Example:
Result:
In this example, bitTestAny
checks if either bit 0 (cheese) or bit 2 (salsa) is set in the taco_flags
field. The binary representation of the flags is:
- 5 (101 in binary): Has cheese (bit 0) and salsa (bit 2)
- 2 (010 in binary): Has lettuce (bit 1)
- 8 (1000 in binary): Has guacamole (bit 3)
The function returns 1 for orders 1 and 2 because they have either cheese or salsa (or both), and 0 for order 3 which has neither.
bitCount
Calculates the number of bits set to one in the binary representation of a number.
Syntax:
Arguments:
x
(Integer or Float): The number to count bits for. The function uses the value’s binary representation in memory.
Returns:
The number of bits set to 1 in the input number. [UInt8]
Example:
Result:
In this example, bitCount
calculates the number of bits set to 1 in each taco_order_id
:
- 42 in binary is 101010, which has 3 bits set to 1
- 255 in binary is 11111111, which has all 8 bits set to 1
- 1024 in binary is 10000000000, which has only 1 bit set to 1
The function does not perform sign extension, so bitCount(toUInt8(-1))
would return 8, as all bits in a UInt8 are set to 1 for the value -1.
bitHammingDistance
Calculates the Hamming distance between the bit representations of two 64-bit integer values.
Syntax:
Arguments:
a
(Int64): First 64-bit integer value.b
(Int64): Second 64-bit integer value.
Returns:
The Hamming distance between a
and b
. [UInt8]
Example:
Result:
In this example, bitHammingDistance
calculates the number of bit positions at which the binary representations of taco_id1
and taco_id2
differ. This can be useful for comparing similarity between taco identifiers or other numeric values.
The Hamming distance can be used with SimHash functions for detecting semi-duplicate strings. A smaller distance suggests a higher likelihood of similarity between the compared values.