diff --git a/libcelt/celt.c b/libcelt/celt.c
index 6b83908cbffb1bc672c104699f074d6612e3680e..b2f875fd85da9b6a15c37e0efbbf2f598dc70677 100644
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -53,8 +53,9 @@
 #include <stdarg.h>
 #include "plc.h"
 
-static const unsigned trim_cdf[12] = {0, 2, 4, 9, 19, 41, 87, 109, 119, 124, 126, 128};
-static const unsigned spread_cdf[5] = {0, 7, 9, 30, 32};
+static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
+/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
+static const unsigned char spread_icdf[4] = {25, 23, 2, 0};
 
 #define COMBFILTER_MAXPERIOD 1024
 #define COMBFILTER_MINPERIOD 16
@@ -975,9 +976,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
    } else {
       st->spread_decision = spreading_decision(st->mode, X, &st->tonal_average, st->spread_decision, effEnd, C, M);
    }
-   /* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
-   ec_encode_bin(enc, spread_cdf[st->spread_decision],
-         spread_cdf[st->spread_decision+1], 5);
+   ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
 
    ALLOC(offsets, st->mode->nbEBands, int);
 
@@ -1030,7 +1029,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
       }
    }
    alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE, st->mode->nbEBands, LM, C, N);
-   ec_encode_bin(enc, trim_cdf[alloc_trim], trim_cdf[alloc_trim+1], 7);
+   ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
 
    /* Variable bitrate */
    if (st->vbr_rate_norm>0)
@@ -1850,7 +1849,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
    ALLOC(tf_res, st->mode->nbEBands, int);
    tf_decode(st->start, st->end, C, isTransient, tf_res, LM, dec);
 
-   spread_decision = ec_dec_cdf(dec, spread_cdf, 5);
+   spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
 
    ALLOC(pulses, st->mode->nbEBands, int);
    ALLOC(offsets, st->mode->nbEBands, int);
@@ -1878,7 +1877,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
    }
 
    ALLOC(fine_quant, st->mode->nbEBands, int);
-   alloc_trim = ec_dec_cdf(dec, trim_cdf, 7);
+   alloc_trim = ec_dec_icdf(dec, trim_icdf, 7);
 
    if (C==2)
    {
diff --git a/libcelt/entdec.h b/libcelt/entdec.h
index d4c06864b3ee1bfb599299090f43b2c98575da36..ac8d43efeb0fb76696a6fd6b23979494eec3e06c 100644
--- a/libcelt/entdec.h
+++ b/libcelt/entdec.h
@@ -113,15 +113,15 @@ ec_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb);
        This must be at least one, and no more than 2**32-1.
   Return: The decoded bits.*/
 ec_uint32 ec_dec_uint(ec_dec *_this,ec_uint32 _ft);
-/*Decodes a symbol given its CDF.
+/*Decodes a symbol given an "inverse" CDF table.
   No call to ec_dec_update() is necessary after this call.
-  _cdf: The CDF, such that symbol s falls in the range [_cdf[s],_cdf[s+1]).
-        The first value must be 0, the last value must be (1<<_ftb), and the
-         values must be monotonicly non-decreasing.
+  _icdf: The "inverse" CDF, such that symbol s falls in the range
+          [s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb.
+         The values must be monotonically non-increasing, and the last value
+          must be 0.
   _ftb: The number of bits of precision in the cumulative distribution.
-  Return: The decoded symbol s, which must have been encoded with
-   ec_encode_bin(enc,_cdf[s],_cdf[s+1],_ftb).*/
-int ec_dec_cdf(ec_dec *_this,const unsigned *_cdf,unsigned _ftb);
+  Return: The decoded symbol s.*/
+int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
 
 /* Decode a bit that has a _prob/65536 probability of being a one */
 int ec_dec_bit_prob(ec_dec *_this,unsigned _prob);
diff --git a/libcelt/entenc.h b/libcelt/entenc.h
index b64ed819b924bbf89da3a6de716ba21fd51e633d..48404404b72317e7ab18583e7892c9e74211c414 100644
--- a/libcelt/entenc.h
+++ b/libcelt/entenc.h
@@ -100,6 +100,15 @@ void ec_enc_bit_prob(ec_enc *_this,int val,unsigned _prob);
 /* Encode a bit that has a 1/(1<<_logp) probability of being a one */
 void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
 
+/*Encodes a symbol given an "inverse" CDF table.
+  _s:    The index of the symbol to encode.
+  _icdf: The "inverse" CDF, such that symbol _s falls in the range
+          [_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb.
+         The values must be monotonically non-increasing, and the last value
+          must be 0.
+  _ftb: The number of bits of precision in the cumulative distribution.*/
+void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
+
 /*Returns the number of bits "used" by the encoded symbols so far.
   This same number can be computed by the decoder, and is suitable for making
    coding decisions.
diff --git a/libcelt/rangedec.c b/libcelt/rangedec.c
index 7dce4a10c837f655a368727b35cdfcb9b8f12fbe..51cb8e2dba009c83eb98009aceb4eb79d527c800 100644
--- a/libcelt/rangedec.c
+++ b/libcelt/rangedec.c
@@ -187,7 +187,7 @@ int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
   return val;
 }
 
-int ec_dec_cdf(ec_dec *_this,const unsigned *_cdf,unsigned _ftb){
+int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){
   ec_uint32 r;
   ec_uint32 d;
   ec_uint32 s;
@@ -199,7 +199,7 @@ int ec_dec_cdf(ec_dec *_this,const unsigned *_cdf,unsigned _ftb){
   val=0;
   do{
     t=s;
-    s=IMUL32(r,(1<<_ftb)-_cdf[++val]);
+    s=IMUL32(r,_icdf[val++]);
   }
   while(d<s);
   _this->dif=d-s;
diff --git a/libcelt/rangeenc.c b/libcelt/rangeenc.c
index 5f27644062f01b7c626bbb44a834ad3560a64a3e..fad9aa6b99547a9421d33f5efc7e6f6a7a96ad3e 100644
--- a/libcelt/rangeenc.c
+++ b/libcelt/rangeenc.c
@@ -169,6 +169,17 @@ void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
   ec_enc_normalize(_this);
 }
 
+void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
+  ec_uint32 r;
+  r=_this->rng>>_ftb;
+  if(_s>0){
+    _this->low+=_this->rng-IMUL32(r,_icdf[_s-1]);
+    _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
+  }
+  else _this->rng-=IMUL32(r,_icdf[_s]);
+  ec_enc_normalize(_this);
+}
+
 void ec_enc_bits(ec_enc *_this,ec_uint32 _fl,unsigned _bits){
   ec_window window;
   int       used;
diff --git a/tests/ectest.c b/tests/ectest.c
index 190beef9030cbd229e9466465c22c215cd3a9a96..7b65c04d429b2987245a0bcc1b6749f3a009a2ff 100644
--- a/tests/ectest.c
+++ b/tests/ectest.c
@@ -188,7 +188,7 @@ int main(int _argc,char **_argv){
     for(j=0;j<sz;j++){
       data[j]=rand()/((RAND_MAX>>1)+1);
       logp1[j]=(rand()%15)+1;
-      enc_method[j]=rand()%3;
+      enc_method[j]=rand()/((RAND_MAX>>2)+1);
       switch(enc_method[j]){
         case 0:{
           ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
@@ -201,6 +201,12 @@ int main(int _argc,char **_argv){
         case 2:{
           ec_enc_bit_logp(&enc,data[j],logp1[j]);
         }break;
+        case 3:{
+          unsigned icdf[2];
+          icdf[0]=1;
+          icdf[1]=0;
+          ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
+        }break;
       }
       tell[j+1]=ec_enc_tell(&enc,3);
     }
@@ -238,11 +244,10 @@ int main(int _argc,char **_argv){
           sym=ec_dec_bit_logp(&dec,logp1[j]);
         }break;
         case 3:{
-          unsigned cdf[3];
-          cdf[0]=0;
-          cdf[1]=(1<<logp1[j])-1;
-          cdf[2]=1<<logp1[j];
-          sym=ec_dec_cdf(&dec,cdf,logp1[j]);
+          unsigned icdf[2];
+          icdf[0]=1;
+          icdf[1]=0;
+          sym=ec_dec_icdf(&dec,icdf,logp1[j]);
         }break;
       }
       if(sym!=data[j]){