online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
/****************************************************************************** Online C Compiler. Code, Compile, Run and Debug C program online. Write your code in this editor and press "Run" button to compile and execute it. *******************************************************************************/ #include <stdio.h> #include <stdint.h> // for uint32_t #include <string.h> // for memcpy #include <math.h> // for frexpf, ldexpf, isinf, nextafterf #define PORTABLE (1) // 0=bit-manipulation of 'float', 1= math library functions uint32_t float_as_uint32 (float a) { uint32_t r; memcpy (&r, &a, sizeof r); return r; } float uint32_as_float (uint32_t a) { float r; memcpy (&r, &a, sizeof r); return r; } /* Compute log(a) with extended precision, returned as a double-float value loghi:loglo. Maximum relative error: 8.5626e-10. */ void my_logf_ext (float a, float *loghi, float *loglo) { const float LOG2_HI = 6.93147182e-1f; // 0x1.62e430p-1 const float LOG2_LO = -1.90465421e-9f; // -0x1.05c610p-29 const float SQRT_HALF = 0.70710678f; float m, r, i, s, t, p, qhi, qlo; int e; /* Reduce argument to m in [sqrt(0.5), sqrt(2.0)] */ #if PORTABLE m = frexpf (a, &e); if (m < SQRT_HALF) { m = m + m; e = e - 1; } i = (float)e; #else // PORTABLE const float POW_TWO_M23 = 1.19209290e-7f; // 0x1.0p-23 const float POW_TWO_P23 = 8388608.0f; // 0x1.0p+23 const float FP32_MIN_NORM = 1.175494351e-38f; // 0x1.0p-126 i = 0.0f; /* fix up denormal inputs */ if (a < FP32_MIN_NORM){ a = a * POW_TWO_P23; i = -23.0f; } e = (float_as_uint32 (a) - float_as_uint32 (SQRT_HALF)) & 0xff800000; m = uint32_as_float (float_as_uint32 (a) - e); i = fmaf ((float)e, POW_TWO_M23, i); #endif // PORTABLE /* Compute q = (m-1)/(m+1) as a double-float qhi:qlo */ p = m + 1.0f; m = m - 1.0f; r = 1.0f / p; qhi = r * m; qlo = r * fmaf (qhi, -m, fmaf (qhi, -2.0f, m)); /* Approximate atanh(q), q in [sqrt(0.5)-1, sqrt(2)-1] */ s = qhi * qhi; r = 0.1293334961f; // 0x1.08c000p-3 r = fmaf (r, s, 0.1419928074f); // 0x1.22cd9cp-3 r = fmaf (r, s, 0.2000148296f); // 0x1.99a162p-3 r = fmaf (r, s, 0.3333332539f); // 0x1.555550p-2 t = fmaf (qhi, qlo + qlo, fmaf (qhi, qhi, -s)); // s:t = (qhi:qlo)**2 p = s * qhi; t = fmaf (s, qlo, fmaf (t, qhi, fmaf (s, qhi, -p))); // p:t = (qhi:qlo)**3 s = fmaf (r, p, fmaf (r, t, qlo)); r = 2 * qhi; /* log(a) = 2 * atanh(q) + i * log(2) */ t = fmaf ( LOG2_HI, i, r); p = fmaf (-LOG2_HI, i, t); s = fmaf ( LOG2_LO, i, fmaf (2.f, s, r - p)); *loghi = p = t + s; // normalize double-float result *loglo = (t - p) + s; } /* Compute exponential base e. No checking for underflow and overflow. Maximum ulp error = 0.86565 */ float my_expf_unchecked (float a) { float f, j, r; int i; // exp(a) = 2**i * exp(f); i = rintf (a / log(2)) j = fmaf (1.442695f, a, 12582912.f) - 12582912.f; // 0x1.715476p0, 0x1.8p23 printf("j:=%f\n", j); f = fmaf (j, -6.93145752e-1f, a); // -0x1.62e400p-1 // log_2_hi printf("f:=%f\n", f); f = fmaf (j, -1.42860677e-6f, f); // -0x1.7f7d1cp-20 // log_2_lo printf("f:=%f\n", f); i = (int)j; printf("i:=%d\n", i); // approximate r = exp(f) on interval [-log(2)/2, +log(2)/2] r = 1.37805939e-3f; // 0x1.694000p-10 printf("r:=%f\n", r); r = fmaf (r, f, 8.37312452e-3f); // 0x1.125edcp-7 printf("r:=%f\n", r); r = fmaf (r, f, 4.16695364e-2f); // 0x1.555b5ap-5 printf("r:=%f\n", r); r = fmaf (r, f, 1.66664720e-1f); // 0x1.555450p-3 printf("r:=%f\n", r); r = fmaf (r, f, 4.99999851e-1f); // 0x1.fffff6p-2 printf("r:=%f\n", r); r = fmaf (r, f, 1.00000000e+0f); // 0x1.000000p+0 printf("r:=%f\n", r); r = fmaf (r, f, 1.00000000e+0f); // 0x1.000000p+0 printf("r:=%f\n", r); // exp(a) = 2**i * r #if PORTABLE r = ldexpf (r, i); printf("r:=%f\nfinal\n", r); #else // PORTABLE float s, t; uint32_t ia = (i > 0) ? 0u : 0x83000000u; s = uint32_as_float (0x7f000000u + ia); t = uint32_as_float (((uint32_t)i << 23) - ia); r = r * s; r = r * t; #endif // PORTABLE return r; } /* a**b = exp (b * log (a)), where a > 0, and log(a) is computed with extended precision as a double-float. Maxiumum error found across 2**42 test cases: 1.97302 ulp @ (0.71162397, -256.672424). */ float my_powf_core (float a, float b) { const float MAX_IEEE754_FLT = uint32_as_float (0x7f7fffff); const float EXP_OVFL_BOUND = 88.7228394f; // 0x1.62e430p+6f; const float EXP_OVFL_UNFL_F = 104.0f; const float MY_INF_F = uint32_as_float (0x7f800000); float lhi, llo, thi, tlo, phi, plo, r; /* compute lhi:llo = log(a) */ my_logf_ext (a, &lhi, &llo); /* compute phi:plo = b * log(a) */ thi = lhi * b; if (fabsf (thi) > EXP_OVFL_UNFL_F) { // definitely overflow / underflow r = (thi < 0.0f) ? 0.0f : MY_INF_F; } else { tlo = fmaf (lhi, b, -thi); tlo = fmaf (llo, b, +tlo); /* normalize intermediate result thi:tlo, giving final result phi:plo */ #if FAST_FADD_RZ phi = __fadd_rz (thi, tlo);// avoid premature ovfl in exp() computation #else // FAST_FADD_RZ phi = thi + tlo; if (phi == EXP_OVFL_BOUND){// avoid premature ovfl in exp() computation #if PORTABLE phi = nextafterf (phi, 0.0f); #else // PORTABLE phi = uint32_as_float (float_as_uint32 (phi) - 1); #endif // PORTABLE } #endif // FAST_FADD_RZ plo = (thi - phi) + tlo; /* exp'(x) = exp(x); exp(x+y) = exp(x) + exp(x) * y, for |y| << |x| */ r = my_expf_unchecked (phi); /* prevent generation of NaN during interpolation due to r = INF */ if (fabsf (r) <= MAX_IEEE754_FLT) { r = fmaf (plo, r, r); } } return r; } float my_powf (float a, float b) { const float MY_INF_F = uint32_as_float (0x7f800000); const float MY_NAN_F = uint32_as_float (0xffc00000); int expo_odd_int; float r; /* special case handling per ISO C specification */ expo_odd_int = fmaf (-2.0f, floorf (0.5f * b), b) == 1.0f; if ((a == 1.0f) || (b == 0.0f)) { r = 1.0f; } else if (isnan (a) || isnan (b)) { r = a + b; // convert SNaN to QNanN or trigger exception } else if (isinf (b)) { r = ((fabsf (a) < 1.0f) != (b < 0.0f)) ? 0.0f : MY_INF_F; if (a == -1.0f) r = 1.0f; } else if (isinf (a)) { r = (b < 0.0f) ? 0.0f : MY_INF_F; if ((a < 0.0f) && expo_odd_int) r = -r; } else if (a == 0.0f) { r = (expo_odd_int) ? (a + a) : 0.0f; if (b < 0.0f) r = copysignf (MY_INF_F, r); } else if ((a < 0.0f) && (b != floorf (b))) { r = MY_NAN_F; } else { r = my_powf_core (fabsf (a), b); if ((a < 0.0f) && expo_odd_int) { r = -r; } } return r; } int main() { printf("%f", my_expf_unchecked(1)); return 0; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue