mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Function bin for uint uses writeBinByte, correct for single zero
This commit is contained in:
parent
cc13787888
commit
231740f2d6
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <bit>
|
||||
|
||||
|
||||
/// Maps 0..15 to 0..9A..F or 0..9a..f correspondingly.
|
||||
@ -46,6 +47,20 @@ inline void writeBinByte(UInt8 byte, void * out)
|
||||
memcpy(out, &bin_byte_to_char_table[static_cast<size_t>(byte) * 8], 8);
|
||||
}
|
||||
|
||||
inline size_t writeBinByteNoLeadZeros(UInt8 byte, char * out)
|
||||
{
|
||||
if (byte == 0)
|
||||
return 0;
|
||||
|
||||
int clz = std::countl_zero(byte);
|
||||
for (Int8 offset = sizeof(UInt8) * 8 - clz - 1; offset >= 0; --offset)
|
||||
{
|
||||
*out = ((byte >> offset) & 1) ? '1' : '0';
|
||||
++out;
|
||||
}
|
||||
return sizeof(UInt8) * 8 - clz;
|
||||
}
|
||||
|
||||
/// Produces hex representation of an unsigned int with leading zeros (for checksums)
|
||||
template <typename TUInt>
|
||||
inline void writeHexUIntImpl(TUInt uint_, char * out, const char * const table)
|
||||
|
@ -1344,30 +1344,32 @@ struct BinImpl
|
||||
static void executeOneUInt(T x, char *& out)
|
||||
{
|
||||
bool was_nonzero = false;
|
||||
T t = 1;
|
||||
|
||||
for (Int8 offset = sizeof(x) * 8 - 1; offset >= 0; --offset)
|
||||
for (int offset = (sizeof(T) - 1) * 8; offset >= 0; offset -= 8)
|
||||
{
|
||||
t = t << offset;
|
||||
if ((x & t) == t)
|
||||
UInt8 byte = x >> offset;
|
||||
|
||||
/// Skip leading zeros
|
||||
if (byte == 0 && !was_nonzero)
|
||||
continue;
|
||||
|
||||
/// First non-zero byte without leading zeros
|
||||
if (was_nonzero)
|
||||
{
|
||||
x = x - t;
|
||||
was_nonzero = true;
|
||||
*out = '1';
|
||||
t = 1;
|
||||
writeBinByte(byte, out);
|
||||
out += word_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = 1;
|
||||
if (!was_nonzero)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*out = '0';
|
||||
size_t written = writeBinByteNoLeadZeros(byte, out);
|
||||
out += written;
|
||||
}
|
||||
was_nonzero = true;
|
||||
}
|
||||
if (!was_nonzero)
|
||||
{
|
||||
*out = '0';
|
||||
++out;
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
++out;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
|
||||
0
|
||||
1
|
||||
1010
|
||||
1111111
|
||||
@ -13,6 +14,14 @@
|
||||
0000000000000000000011000011110101011101010100111010101000000001
|
||||
0011000100110010001100110011001100110010001101000011001000110100
|
||||
0011000100110010001100110011001100110010001101000011001000110100
|
||||
0011000100110010001100110011001100110010001101000011001000110100
|
||||
0011000100110010001100110011001100110010001101000011001000110100
|
||||
|
||||
0
|
||||
10
|
||||
测试
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
|
@ -1,3 +1,4 @@
|
||||
select bin('');
|
||||
select bin(0);
|
||||
select bin(1);
|
||||
select bin(10);
|
||||
@ -12,8 +13,17 @@ select bin(toFloat64(1.2));
|
||||
select bin(toDecimal32(1.2, 8));
|
||||
select bin(toDecimal64(1.2, 17));
|
||||
select bin('12332424');
|
||||
select bin(materialize('12332424'));
|
||||
select bin(toNullable(materialize('12332424')));
|
||||
select bin(toLowCardinality(materialize('12332424')));
|
||||
|
||||
select unbin('');
|
||||
select unbin('00110000'); -- 0
|
||||
select unbin('0011000100110000'); -- 10
|
||||
select unbin('111001101011010110001011111010001010111110010101'); -- 测试
|
||||
select unbin(materialize('00110000'));
|
||||
select unbin(toNullable(materialize('00110000')));
|
||||
select unbin(toLowCardinality(materialize('00110000')));
|
||||
|
||||
select unbin(bin('')) == '';
|
||||
select bin(unbin('')) == '';
|
||||
|
Loading…
Reference in New Issue
Block a user