/* * Copyright (c) 2019 Vestas Wind Systems A/S * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #define MAX_D_ITTERATIONS 8 /* usually converges in 5 loops */ /* this ensures we break out of the loop */ #define MAX_D_ERROR_COUNT 5 /* when result almost converges, stop */ #define EXP_MASK64 GENMASK64(62, 52) typedef union { double d; int64_t i; } int64double_t; double sqrt(double square) { int i; int64_t exponent; int64double_t root; int64double_t last; int64double_t p_square; p_square.d = square; if (square == 0.0) { return square; } if (square < 0.0) { return (square - square) / (square - square); } /* we need a good starting guess so that this will converge quickly, * we can do this by dividing the exponent part of the float by 2 * this assumes IEEE-754 format doubles */ exponent = ((p_square.i & EXP_MASK64) >> 52) - 1023; if (exponent == 0x7FF - 1023) { /* the number is a NAN or inf, return NaN or inf */ return square + square; } exponent /= 2; root.i = (p_square.i & ~EXP_MASK64) | (exponent + 1023) << 52; for (i = 0; i < MAX_D_ITTERATIONS; i++) { last = root; root.d = (root.d + square / root.d) * 0.5; /* if (llabs(*p_root-*p_last)