File fix-chromosome-32bit.patch of Package liquid-dsp

Description: Fix chromosomes for sizeof (unsigned long) == 32
 In the chromosome struct, the maximum value of a trait is stored in an
 unsigned long (which is 32 bits on a typical 32 bit architecture) and up to 32
 bits per trait are allowed.  When the full 32 bits per trait were used, the
 value stored in max_value is 1 << 32 which is truncated to zero on 32 bit
 architectures. This causes the limit check in chromosome_init() to always
 fail.
 .
 While it would be sufficient to change the comparison from v >= max_value to
 v > (max_value - 1), change the setting of max_value to "(1<<bits)-1". This
 has the advantage of being the actual maximum value and therefore more
 appropriate for the name.
Author: Andreas Bombe <aeb@debian.org>
Last-Update: 2023-10-18
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/src/optim/src/chromosome.c
+++ b/src/optim/src/chromosome.c
@@ -62,7 +62,7 @@
     for (i=0; i<q->num_traits; i++) {
         q->bits_per_trait[i] = _bits_per_trait[i];
 
-        q->max_value[i] = 1LU << q->bits_per_trait[i];
+        q->max_value[i] = (1ULL << q->bits_per_trait[i]) - 1;
         q->traits[i] = 0LU;
 
         q->num_bits += q->bits_per_trait[i];
@@ -80,7 +80,7 @@
     // validate input
     if (_num_traits == 0)
         return liquid_error_config("chromosome_create_basic(), must have at least one trait");
-    if (_bits_per_trait == 0 || _bits_per_trait > 64)
+    if (_bits_per_trait == 0 || _bits_per_trait > LIQUID_CHROMOSOME_MAX_SIZE)
         return liquid_error_config("chromosome_create_basic(), bits per trait out of range");
 
     unsigned int * bpt = (unsigned int *) malloc(_num_traits*sizeof(unsigned int));
@@ -179,7 +179,7 @@
     unsigned int i;
     for (i=0; i<_c->num_traits; i++) {
         //printf("===> [%3u] bits:%3u, max:%12lu, value:%12lu\n", i, _c->bits_per_trait[i], _c->max_value[i], _v[i]);
-        if (_v[i] >= _c->max_value[i])
+        if (_v[i] > _c->max_value[i])
             return liquid_error(LIQUID_EIRANGE,"chromosome_init(), value exceeds maximum");
 
         _c->traits[i] = _v[i];
@@ -197,7 +197,7 @@
             return liquid_error(LIQUID_EIRANGE,"chromosome_initf(), value must be in [0,1]");
 
         // quantize sample
-        unsigned long N = 1LU << _c->bits_per_trait[i];
+        unsigned long N = (1ULL << _c->bits_per_trait[i]) - 1;
         _c->traits[i] = (unsigned long) floorf( _v[i] * N );
         //printf("===> [%3u] quantizing %8.2f, bits:%3u, N:%12lu, trait:%12lu/%12lu => %12.8f\n",
         //    i, _v[i], _c->bits_per_trait[i], N, _c->traits[i], _c->max_value[i], chromosome_valuef(_c,i));
@@ -295,7 +295,7 @@
 {
     unsigned int i;
     for (i=0; i<_q->num_traits; i++)
-        _q->traits[i] = rand() & (_q->max_value[i]-1LU);
+        _q->traits[i] = rand() & _q->max_value[i];
     return LIQUID_OK;
 }
 
@@ -306,7 +306,7 @@
         liquid_error(LIQUID_EIRANGE,"chromosome_valuef(), trait index exceeded");
         return 0.0f;
     }
-    return (float) (_q->traits[_index]) / (float)(_q->max_value[_index]-1LU);
+    return (float) (_q->traits[_index]) / (float)_q->max_value[_index];
 }
 
 unsigned int chromosome_value(chromosome   _q,
openSUSE Build Service is sponsored by