discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Swig issue with floats versus doubles


From: Michael Piscopo
Subject: Re: Swig issue with floats versus doubles
Date: Sun, 8 Dec 2019 19:23:42 -0500

Thanks Nate!  Looks like any block anyone's made that may use a float instead of a double for a sample rate or frequency variable may run in to these rounding errors due to the size of a foat.  I have a couple (mine and a few others') I'm scrubbing through now that need some correcting.  I'll do my best to let folks know as I find it.

Mike


On Sun, Dec 8, 2019 at 6:29 PM Nate Temple <address@hidden> wrote:

* The first occurrence is at 16777216+1 or 2^24

On Sun, Dec 8, 2019 at 3:26 PM Nate Temple <address@hidden> wrote:
I ended up making a test script to shed some more light on where this starts at.

The first occurrence is at 16777217

Checkpoint: 16000000.000000
f: 16777217 D: 16777217 F: 16777216 Diff: 1
f: 16777219 D: 16777219 F: 16777220 Diff: -1
f: 16777221 D: 16777221 F: 16777220 Diff: 1
f: 16777223 D: 16777223 F: 16777224 Diff: -1
f: 16777225 D: 16777225 F: 16777224 Diff: 1
f: 16777227 D: 16777227 F: 16777228 Diff: -1


At 50e6 it's losing more bits:

f: 50000001 D: 50000001 F: 50000000 Diff: 1
f: 50000002 D: 50000002 F: 50000000 Diff: 2
f: 50000003 D: 50000003 F: 50000004 Diff: -1
f: 50000005 D: 50000005 F: 50000004 Diff: 1
f: 50000006 D: 50000006 F: 50000008 Diff: -2
f: 50000007 D: 50000007 F: 50000008 Diff: -1
f: 50000009 D: 50000009 F: 50000008 Diff: 1
f: 50000010 D: 50000010 F: 50000008 Diff: 2

100e6:

f: 100000001 D: 100000001 F: 100000000 Diff: 1
f: 100000002 D: 100000002 F: 100000000 Diff: 2
f: 100000003 D: 100000003 F: 100000000 Diff: 3
f: 100000004 D: 100000004 F: 100000000 Diff: 4
f: 100000005 D: 100000005 F: 100000008 Diff: -3
f: 100000006 D: 100000006 F: 100000008 Diff: -2
f: 100000007 D: 100000007 F: 100000008 Diff: -1

150e6:

f: 150000001 D: 150000001 F: 150000000 Diff: 1
f: 150000002 D: 150000002 F: 150000000 Diff: 2
f: 150000003 D: 150000003 F: 150000000 Diff: 3
f: 150000004 D: 150000004 F: 150000000 Diff: 4
f: 150000005 D: 150000005 F: 150000000 Diff: 5
f: 150000006 D: 150000006 F: 150000000 Diff: 6
f: 150000007 D: 150000007 F: 150000000 Diff: 7
f: 150000008 D: 150000008 F: 150000000 Diff: 8
f: 150000009 D: 150000009 F: 150000016 Diff: -7
f: 150000010 D: 150000010 F: 150000016 Diff: -6
f: 150000011 D: 150000011 F: 150000016 Diff: -5
f: 150000012 D: 150000012 F: 150000016 Diff: -4
f: 150000013 D: 150000013 F: 150000016 Diff: -3
f: 150000014 D: 150000014 F: 150000016 Diff: -2
f: 150000015 D: 150000015 F: 150000016 Diff: -1


test script:

import filerepeater

freq = 15000000
debug = False

while(1):
    freq += 1
    out = 'f: %2.f' % freq
    fs=filerepeater.AdvFileSink(1,1,'/tmp','test',freq,2.4e6,0,0,True,False,False,8,False,False)
    fs.setTest(freq)
    d_freq = fs.getTest()

    fs.setTestFloat(freq)
    f_freq = fs.getTestFloat()

    if (d_freq != freq) or (f_freq != freq) or (debug == True):
        f_diff = freq - f_freq
        out += " D: %2.f F: %2.f Diff: %0.f" % (d_freq, f_freq, f_diff)
        print(out)

    if freq % 1000000 == 0:
        print("Checkpoint: %f" % freq)

On Sun, Dec 8, 2019 at 2:52 PM Michael Piscopo <address@hidden> wrote:
So a few of us have spent a few hours trying to narrow this one down and it's now reproducible, but I'm afraid this may have some far-reaching ramifications.....

Swig-wrapped C++ functions using floats seem to have something like a power-of-2 rounding issue going on.

if you define functions in your top-level .h file like this:
      virtual double getTest() const =0;
      virtual void setTest(double newValue) =0;

      virtual float getTestFloat() const =0;
      virtual void setTestFloat(float newValue) =0;

Then implement them like this in your _impl.h file:
      double d_test=0.0;
      float d_testfloat = 0.0;

      virtual double getTest() const {return d_test;};
      virtual void setTest(double newValue) { d_test = newValue; };

      virtual float getTestFloat() const {return d_testfloat;};
      virtual void setTestFloat(float newValue) { d_testfloat = newValue; };


Go ahead and build/install your OOT module then try the get/set with a value like a frequency such as 158355000.0.  The float will return 158355008.0 whereas the double will return 158355000.0.

gr-filerepeater is where I was troubleshooting and added the testing hooks, so if you git pull the latest and build it (I added the testing hooks today), then go interactive python from a command-line and try this:
import filerepeater
fs=filerepeater.AdvFileSink(1,1,'/tmp','test',158355000.00,2.4e6,0,0,True,False,False,8,False,False)
fs.setTest(158355000.0)
fs.getTest()
fs.setTestFloat(158355000.0)
fs.getTestFloat()

You'll see the results. 

I'm not sure where else in GR the legacy / smaller float versus double may cause processing issues with this.

Any thoughts?
Mike


reply via email to

[Prev in Thread] Current Thread [Next in Thread]