Implementation:ClickHouse ClickHouse Musl Pow
| Knowledge Sources | |
|---|---|
| Domains | Mathematics, Portability |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
Double precision power function computing x^y with 0.54 ULP worst-case error.
Description
This implementation computes `pow(x, y)` by evaluating `exp(y * log(x))` using optimized inline logarithm and exponential functions with lookup tables. It handles extensive special cases including signed zeros, infinities, NaN propagation, integer exponents, and proper sign handling for negative bases with integer exponents. The code achieves high accuracy through FMA-aware polynomial evaluation, split-precision arithmetic, and careful range reduction.
Usage
Use this function for portable power computations across different systems where consistent numerical behavior and high accuracy are required, particularly when the system's native `pow` implementation is unavailable or unreliable.
Code Reference
Source Location
- Repository: ClickHouse
- File: base/glibc-compatibility/musl/pow.c
- Lines: 1-343
Signature
double pow(double x, double y);
Import
#include <math.h>
I/O Contract
| Input Pattern | Output | Special Behavior |
|---|---|---|
| pow(±0, y) where y < 0 | ±∞ | Raises divide-by-zero |
| pow(±0, y) where y > 0 | ±0 | Sign matches y's parity if y is odd integer |
| pow(-1, ±∞) | 1 | Limit behavior |
| pow(1, y) for any y | 1 | Even if y is NaN |
| pow(x, ±0) for any x | 1 | Even if x is NaN |
| pow(x, 1) | x | Identity |
| pow(x, y) where x < 0, y non-integer | NaN | Raises invalid |
| pow(x, y) where x < 0, y odd integer | -(abs(x)^y) | Preserves sign |
| pow(x, y) where x < 0, y even integer | abs(x)^y | Positive result |
| x| < 1 | 0 or ∞ | Depends on sign of infinity |
| x| > 1 | ∞ or 0 | Depends on sign of infinity |
| pow(±∞, y) where y < 0 | 0 | May preserve sign for odd y |
| pow(±∞, y) where y > 0 | ±∞ | Sign depends on parity |
Usage Examples
// Basic power computation
double base = 2.0;
double exponent = 10.0;
double result = pow(base, exponent); // 1024.0
// Negative base with integer exponent
double neg_result = pow(-2.0, 3.0); // -8.0 (odd exponent)
double pos_result = pow(-2.0, 4.0); // 16.0 (even exponent)
// Fractional exponents (roots)
double sqrt_val = pow(16.0, 0.5); // 4.0
double cube_root = pow(27.0, 1.0/3.0); // 3.0
// Special cases
double one = pow(5.0, 0.0); // 1.0 (anything^0 = 1)
double base_one = pow(1.0, 1e100); // 1.0 (1^anything = 1)
// Overflow and underflow
double overflow = pow(2.0, 1100.0); // INFINITY
double underflow = pow(2.0, -1100.0); // 0.0
// Error handling for invalid operations
double invalid = pow(-2.0, 2.5); // NaN (negative^non-integer)
// Practical calculations
double compound_interest(double principal, double rate, double years) {
return principal * pow(1.0 + rate, years);
}
// Distance computation
double distance(double x1, double y1, double x2, double y2) {
return pow(pow(x2 - x1, 2.0) + pow(y2 - y1, 2.0), 0.5);
}
// Check for exact integer to handle signs correctly
int is_odd_integer(double y) {
if (y != floor(y)) return 0;
long long yi = (long long)y;
return (yi & 1) != 0;
}
double safe_pow(double x, double y) {
if (x < 0 && !is_odd_integer(y) && y != floor(y)) {
return NAN; // Would produce complex result
}
return pow(x, y);
}