Libav
|
00001 /* 00002 * portable IEEE float/double read/write functions 00003 * 00004 * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> 00005 * 00006 * This file is part of FFmpeg. 00007 * 00008 * FFmpeg is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * FFmpeg is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with FFmpeg; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00028 #include <stdint.h> 00029 #include <math.h> 00030 #include "intfloat_readwrite.h" 00031 00032 double av_int2dbl(int64_t v){ 00033 if(v+v > 0xFFEULL<<52) 00034 return 0.0/0.0; 00035 return ldexp(((v&((1LL<<52)-1)) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075); 00036 } 00037 00038 float av_int2flt(int32_t v){ 00039 if(v+v > 0xFF000000U) 00040 return 0.0/0.0; 00041 return ldexp(((v&0x7FFFFF) + (1<<23)) * (v>>31|1), (v>>23&0xFF)-150); 00042 } 00043 00044 double av_ext2dbl(const AVExtFloat ext){ 00045 uint64_t m = 0; 00046 int e, i; 00047 00048 for (i = 0; i < 8; i++) 00049 m = (m<<8) + ext.mantissa[i]; 00050 e = (((int)ext.exponent[0]&0x7f)<<8) | ext.exponent[1]; 00051 if (e == 0x7fff && m) 00052 return 0.0/0.0; 00053 e -= 16383 + 63; /* In IEEE 80 bits, the whole (i.e. 1.xxxx) 00054 * mantissa bit is written as opposed to the 00055 * single and double precision formats. */ 00056 if (ext.exponent[0]&0x80) 00057 m= -m; 00058 return ldexp(m, e); 00059 } 00060 00061 int64_t av_dbl2int(double d){ 00062 int e; 00063 if ( !d) return 0; 00064 else if(d-d) return 0x7FF0000000000000LL + ((int64_t)(d<0)<<63) + (d!=d); 00065 d= frexp(d, &e); 00066 return (int64_t)(d<0)<<63 | (e+1022LL)<<52 | (int64_t)((fabs(d)-0.5)*(1LL<<53)); 00067 } 00068 00069 int32_t av_flt2int(float d){ 00070 int e; 00071 if ( !d) return 0; 00072 else if(d-d) return 0x7F800000 + ((d<0)<<31) + (d!=d); 00073 d= frexp(d, &e); 00074 return (d<0)<<31 | (e+126)<<23 | (int64_t)((fabs(d)-0.5)*(1<<24)); 00075 } 00076 00077 AVExtFloat av_dbl2ext(double d){ 00078 struct AVExtFloat ext= {{0}}; 00079 int e, i; double f; uint64_t m; 00080 00081 f = fabs(frexp(d, &e)); 00082 if (f >= 0.5 && f < 1) { 00083 e += 16382; 00084 ext.exponent[0] = e>>8; 00085 ext.exponent[1] = e; 00086 m = (uint64_t)ldexp(f, 64); 00087 for (i=0; i < 8; i++) 00088 ext.mantissa[i] = m>>(56-(i<<3)); 00089 } else if (f != 0.0) { 00090 ext.exponent[0] = 0x7f; ext.exponent[1] = 0xff; 00091 if (f != 1/0.0) 00092 ext.mantissa[0] = ~0; 00093 } 00094 if (d < 0) 00095 ext.exponent[0] |= 0x80; 00096 return ext; 00097 } 00098