mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Fixed extremes calculation in presense of NaNs [#METR-22882].
This commit is contained in:
parent
00176b9c5e
commit
9c39a324f2
@ -120,6 +120,27 @@ template <> inline UInt64 unionCastToUInt64(Float32 x)
|
||||
}
|
||||
|
||||
|
||||
/// To be sure, that this function is zero-cost for non-floating point types.
|
||||
template <typename T>
|
||||
inline bool isNaN(T x)
|
||||
{
|
||||
return std::is_floating_point<T>::value ? isnan(x) : false;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type NaNOrZero()
|
||||
{
|
||||
return std::numeric_limits<T>::quiet_NaN();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<!std::is_floating_point<T>::value, T>::type NaNOrZero()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Шаблон столбцов, которые используют для хранения простой массив.
|
||||
*/
|
||||
template <typename T>
|
||||
@ -435,16 +456,35 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
T cur_min = data[0];
|
||||
T cur_max = data[0];
|
||||
bool has_value = false;
|
||||
|
||||
for (size_t i = 1; i < size; ++i)
|
||||
/** Skip all NaNs in extremes calculation.
|
||||
* If all values are NaNs, then return NaN.
|
||||
* NOTE: There exist many different NaNs.
|
||||
* Different NaN could be returned: not bit-exact value as one of NaNs from column.
|
||||
*/
|
||||
|
||||
T cur_min = NaNOrZero<T>();
|
||||
T cur_max = NaNOrZero<T>();
|
||||
|
||||
for (const T x : data)
|
||||
{
|
||||
if (data[i] < cur_min)
|
||||
cur_min = data[i];
|
||||
if (isNaN(x))
|
||||
continue;
|
||||
|
||||
if (data[i] > cur_max)
|
||||
cur_max = data[i];
|
||||
if (!has_value)
|
||||
{
|
||||
cur_min = x;
|
||||
cur_max = x;
|
||||
has_value = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (x < cur_min)
|
||||
cur_min = x;
|
||||
|
||||
if (x > cur_max)
|
||||
cur_max = x;
|
||||
}
|
||||
|
||||
min = typename NearestFieldType<T>::Type(cur_min);
|
||||
|
@ -0,0 +1,48 @@
|
||||
3
|
||||
1
|
||||
2
|
||||
|
||||
1
|
||||
3
|
||||
nan
|
||||
1
|
||||
2
|
||||
|
||||
1
|
||||
2
|
||||
3
|
||||
nan
|
||||
2
|
||||
|
||||
2
|
||||
3
|
||||
3
|
||||
1
|
||||
nan
|
||||
|
||||
1
|
||||
3
|
||||
nan
|
||||
nan
|
||||
2
|
||||
|
||||
2
|
||||
2
|
||||
nan
|
||||
1
|
||||
nan
|
||||
|
||||
1
|
||||
1
|
||||
3
|
||||
nan
|
||||
nan
|
||||
|
||||
3
|
||||
3
|
||||
nan
|
||||
nan
|
||||
nan
|
||||
|
||||
nan
|
||||
nan
|
@ -0,0 +1,8 @@
|
||||
SELECT arrayJoin([3, 1, 2]) SETTINGS extremes = 1;
|
||||
SELECT arrayJoin([nan, 1, 2]) SETTINGS extremes = 1;
|
||||
SELECT arrayJoin([3, nan, 2]) SETTINGS extremes = 1;
|
||||
SELECT arrayJoin([3, 1, nan]) SETTINGS extremes = 1;
|
||||
SELECT arrayJoin([nan, nan, 2]) SETTINGS extremes = 1;
|
||||
SELECT arrayJoin([nan, 1, nan]) SETTINGS extremes = 1;
|
||||
SELECT arrayJoin([3, nan, nan]) SETTINGS extremes = 1;
|
||||
SELECT arrayJoin([nan, nan, nan]) SETTINGS extremes = 1;
|
Loading…
Reference in New Issue
Block a user