{"record":{"id":"57c65fbfdb3872b0","repo":"databendlabs/databend","slug":"pow-resulted-in-nan","errorCode":null,"errorMessage":"Pow resulted in NaN","messagePattern":"Pow resulted in NaN","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/common/base/src/base/ordered_float.rs","lineNumber":1509,"sourceCode":"            }\n        }\n    };\n}\n\nimpl_not_nan_binop! {Add, add, AddAssign, add_assign}\nimpl_not_nan_binop! {Sub, sub, SubAssign, sub_assign}\nimpl_not_nan_binop! {Mul, mul, MulAssign, mul_assign}\nimpl_not_nan_binop! {Div, div, DivAssign, div_assign}\nimpl_not_nan_binop! {Rem, rem, RemAssign, rem_assign}\n\n// Will panic if NaN value is return from the operation\nmacro_rules! impl_not_nan_pow {\n    ($inner:ty, $rhs:ty) => {\n        impl Pow<$rhs> for NotNan<$inner> {\n            type Output = NotNan<$inner>;\n            #[inline]\n            fn pow(self, rhs: $rhs) -> NotNan<$inner> {\n                NotNan::new(<$inner>::pow(self.0, rhs)).expect(\"Pow resulted in NaN\")\n            }\n        }\n\n        impl<'a> Pow<&'a $rhs> for NotNan<$inner> {\n            type Output = NotNan<$inner>;\n            #[inline]\n            fn pow(self, rhs: &'a $rhs) -> NotNan<$inner> {\n                NotNan::new(<$inner>::pow(self.0, *rhs)).expect(\"Pow resulted in NaN\")\n            }\n        }\n\n        impl<'a> Pow<$rhs> for &'a NotNan<$inner> {\n            type Output = NotNan<$inner>;\n            #[inline]\n            fn pow(self, rhs: $rhs) -> NotNan<$inner> {\n                NotNan::new(<$inner>::pow(self.0, rhs)).expect(\"Pow resulted in NaN\")\n            }\n        }","sourceCodeStart":1491,"sourceCodeEnd":1527,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/common/base/src/base/ordered_float.rs#L1491-L1527","documentation":"This is the Pow impl for NotNan<inner> with an owned rhs (from the impl_not_nan_pow macro): it computes `<$inner>::pow(self.0, rhs)` and passes the result to NotNan::new, panicking with this message if the power result is NaN. powf/powi yields NaN for cases like negative base with fractional exponent, or inf/NaN operands.","triggerScenarios":"Calling `pow` (or the `**`/Pow operator) on NotNan<f32/f64> where the base is negative and the exponent is fractional (e.g. (-2.0).pow(0.5)), or where base/exponent combine to NaN via inf - inf semantics in powf.","commonSituations":"Root/sqrt-like computations (0.5 exponent) applied to values that can be negative, or exponentiating values that previously overflowed to inf.","solutions":["Check `(base >= 0.0 || exponent.fract() == 0.0)` and both operands finite before calling pow.","Use fallible `NotNan::new(base.0.pow(exp)).ok()` and handle the NaN case explicitly.","For fractional powers of negatives, use complex arithmetic or clamp/skip the value."],"exampleFix":"// before\nlet root = notnan_base.pow(0.5); // panics for negative base\n// after\nlet root = if **base >= 0.0 { base.pow(0.5) } else { None };","handlingStrategy":"validation","validationCode":"fn can_pow(base: &NotNan<f64>, exp: f64) -> bool {\n    exp.is_finite() && (**base >= 0.0 || exp.fract() == 0.0)\n}","typeGuard":"fn is_safe_pow_base(x: f64, exp: f64) -> bool { x >= 0.0 || exp.fract() == 0.0 }","tryCatchPattern":"let r = std::panic::catch_unwind(|| notnan_base.pow(0.5)).ok();","preventionTips":["Only apply fractional exponents to non-negative bases.","Check base and exponent are finite before pow.","Use a checked helper (NotNan::new(...).ok()) for pow in generic code."],"tags":["rust","float","nan","pow","exponentiation","panic"],"backgroundTag":"nan-arithmetic-panic","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}