1570af302Sopenharmony_ci#include <math.h> 2570af302Sopenharmony_ci#include <stdint.h> 3570af302Sopenharmony_ci 4570af302Sopenharmony_cidouble scalbn(double x, int n) 5570af302Sopenharmony_ci{ 6570af302Sopenharmony_ci union {double f; uint64_t i;} u; 7570af302Sopenharmony_ci double_t y = x; 8570af302Sopenharmony_ci 9570af302Sopenharmony_ci if (n > 1023) { 10570af302Sopenharmony_ci y *= 0x1p1023; 11570af302Sopenharmony_ci n -= 1023; 12570af302Sopenharmony_ci if (n > 1023) { 13570af302Sopenharmony_ci y *= 0x1p1023; 14570af302Sopenharmony_ci n -= 1023; 15570af302Sopenharmony_ci if (n > 1023) 16570af302Sopenharmony_ci n = 1023; 17570af302Sopenharmony_ci } 18570af302Sopenharmony_ci } else if (n < -1022) { 19570af302Sopenharmony_ci /* make sure final n < -53 to avoid double 20570af302Sopenharmony_ci rounding in the subnormal range */ 21570af302Sopenharmony_ci y *= 0x1p-1022 * 0x1p53; 22570af302Sopenharmony_ci n += 1022 - 53; 23570af302Sopenharmony_ci if (n < -1022) { 24570af302Sopenharmony_ci y *= 0x1p-1022 * 0x1p53; 25570af302Sopenharmony_ci n += 1022 - 53; 26570af302Sopenharmony_ci if (n < -1022) 27570af302Sopenharmony_ci n = -1022; 28570af302Sopenharmony_ci } 29570af302Sopenharmony_ci } 30570af302Sopenharmony_ci u.i = (uint64_t)(0x3ff+n)<<52; 31570af302Sopenharmony_ci x = y * u.f; 32570af302Sopenharmony_ci return x; 33570af302Sopenharmony_ci} 34