changeset 33736:a5a54c7a15ce

Fix the precision loss in float -> 32bit conversion case, introduced by my earlier commit. Instead use method proposed by Reimar. Also, avoid using ldexp, it is slower than multiply with constant.
author iive
date Wed, 06 Jul 2011 23:35:39 +0000
parents 84defaf2e7f8
children 71c29e8ec68f
files libaf/af_format.c
diffstat 1 files changed, 10 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libaf/af_format.c	Tue Jul 05 16:50:52 2011 +0000
+++ b/libaf/af_format.c	Wed Jul 06 23:35:39 2011 +0000
@@ -489,15 +489,21 @@
     break;
   case(3):
     for(i=0;i<len;i++){
-      f = ldexp(in[i], 23);
+      f = in[i] * 8388608;
       store24bit(out, i,   av_clip(lrintf(f), -1*(1<<23), (1<<23)-1) << 8);
     }
     break;
   case(4):
     for(i=0;i<len;i++){
-      f = ldexp(in[i], 23);
-      //The mantissa is only 23 bit, that's all the precision there is.
-      ((int32_t*)out)[i] = av_clip(lrintf(f), -1*(1<<23), (1<<23)-1) << 8;
+      f = in[i];
+      if (f <= -1.0)
+        ((int32_t*)out)[i] = INT_MIN;
+      else
+      if (f >=  1.0)//no need to use corrected constant, rounding won't cause overflow
+        ((int32_t*)out)[i] = INT_MAX;
+      else
+        ((int32_t*)out)[i] = lrintf(f*2147483648.0);
+
     }
     break;
   }