Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
double_conversion.c
00001 /* Conversion routines for platforms that do not support 'double' directly. */ 00002 00003 #include "double_conversion.h" 00004 #include <math.h> 00005 00006 typedef union { 00007 float f; 00008 uint32_t i; 00009 } conversion_t; 00010 00011 /* Note: IEE 754 standard specifies float formats as follows: 00012 * Single precision: sign, 8-bit exp, 23-bit frac. 00013 * Double precision: sign, 11-bit exp, 52-bit frac. 00014 */ 00015 00016 uint64_t float_to_double(float value) 00017 { 00018 conversion_t in; 00019 in.f = value; 00020 uint8_t sign; 00021 int16_t exponent; 00022 uint64_t mantissa; 00023 00024 /* Decompose input value */ 00025 sign = (in.i >> 31) & 1; 00026 exponent = ((in.i >> 23) & 0xFF) - 127; 00027 mantissa = in.i & 0x7FFFFF; 00028 00029 if (exponent == 128) 00030 { 00031 /* Special value (NaN etc.) */ 00032 exponent = 1024; 00033 } 00034 else if (exponent == -127) 00035 { 00036 if (!mantissa) 00037 { 00038 /* Zero */ 00039 exponent = -1023; 00040 } 00041 else 00042 { 00043 /* Denormalized */ 00044 mantissa <<= 1; 00045 while (!(mantissa & 0x800000)) 00046 { 00047 mantissa <<= 1; 00048 exponent--; 00049 } 00050 mantissa &= 0x7FFFFF; 00051 } 00052 } 00053 00054 /* Combine fields */ 00055 mantissa <<= 29; 00056 mantissa |= (uint64_t)(exponent + 1023) << 52; 00057 mantissa |= (uint64_t)sign << 63; 00058 00059 return mantissa; 00060 } 00061 00062 float double_to_float(uint64_t value) 00063 { 00064 uint8_t sign; 00065 int16_t exponent; 00066 uint32_t mantissa; 00067 conversion_t out; 00068 00069 /* Decompose input value */ 00070 sign = (value >> 63) & 1; 00071 exponent = ((value >> 52) & 0x7FF) - 1023; 00072 mantissa = (value >> 28) & 0xFFFFFF; /* Highest 24 bits */ 00073 00074 /* Figure if value is in range representable by floats. */ 00075 if (exponent == 1024) 00076 { 00077 /* Special value */ 00078 exponent = 128; 00079 } 00080 else if (exponent > 127) 00081 { 00082 /* Too large */ 00083 if (sign) 00084 return -INFINITY; 00085 else 00086 return INFINITY; 00087 } 00088 else if (exponent < -150) 00089 { 00090 /* Too small */ 00091 if (sign) 00092 return -0.0f; 00093 else 00094 return 0.0f; 00095 } 00096 else if (exponent < -126) 00097 { 00098 /* Denormalized */ 00099 mantissa |= 0x1000000; 00100 mantissa >>= (-126 - exponent); 00101 exponent = -127; 00102 } 00103 00104 /* Round off mantissa */ 00105 mantissa = (mantissa + 1) >> 1; 00106 00107 /* Check if mantissa went over 2.0 */ 00108 if (mantissa & 0x800000) 00109 { 00110 exponent += 1; 00111 mantissa &= 0x7FFFFF; 00112 mantissa >>= 1; 00113 } 00114 00115 /* Combine fields */ 00116 out.i = mantissa; 00117 out.i |= (uint32_t)(exponent + 127) << 23; 00118 out.i |= (uint32_t)sign << 31; 00119 00120 return out.f; 00121 } 00122 00123
Generated on Thu Jul 14 2022 02:43:24 by
1.7.2