Function bin for uint uses writeBinByte, correct for single zero

This commit is contained in:
vdimir 2021-07-05 14:44:50 +03:00
parent cc13787888
commit 231740f2d6
No known key found for this signature in database
GPG Key ID: F57B3E10A21DBB31
4 changed files with 52 additions and 16 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -1,4 +1,5 @@
0
1
1010
1111111
@ -13,6 +14,14 @@
0000000000000000000011000011110101011101010100111010101000000001
0011000100110010001100110011001100110010001101000011001000110100
0011000100110010001100110011001100110010001101000011001000110100
0011000100110010001100110011001100110010001101000011001000110100
0011000100110010001100110011001100110010001101000011001000110100
0
10
测试
0
0
0
1
1

View File

@ -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('')) == '';