Home > front end >  How to change the precision of a value in a pmt pairs
How to change the precision of a value in a pmt pairs

Time:10-12

I am trying to realize a block in gnuradio. It must send a message to the output and command the frequency of a signal source block. The message is a pmt pairs which contains the frequency value in the cdr field. When I put it into the pairs, its precision decreases a lot. For example, with this code

import numpy as np
import pmt

freqval = np.float64(123494235.48994166)
msg = pmt.cons(pmt.intern("freq"), pmt.to_pmt(freqval))

print("freqval : ", freqval)
print("msg : ", msg)

freqval = np.float64(123.49423548994166)
msg = pmt.cons(pmt.intern("freq"), pmt.to_pmt(freqval))

print("freqval : ", freqval)
print("msg : ", msg)

i get

freqval :  123494235.48994166
msg :  (freq . 1.23494e 08)
freqval :  123.49423548994166
msg :  (freq . 123.494)

while I want the value in the msg to be the same as the one contained in freqval. I tried to replace to_pmt() whith from_float() and from_double(), but nothing changed, and making the value as string, but gnuradio raises the warning

gr::log :WARN: sig_source0 - frequency value needs to be a number

Is there a way to change the precision of the pmt pairs value?

CodePudding user response:

This is just the precision of the "pretty print string representation". When you convert your PMT back to a python float or a C double, you should get sufficient precision.

> value = 1/3
# one third has very many fractional digits – it 
# can't be exactly represented in base 10
# but it can't even be exactly stored in a float,
# because 1/3 can also not be exactly represented
# in binary.
> print(value)
0.3333333333333333
# note how most of these digits are just
# "made up (i.e. the closest approximation to 1/3
# in binary of given length)"; python floating points
# don't have 50 significant digits!
> print(f"{value:.50f}"
0.33333333333333331482961625624739099293947219848633
> a = pmt.pmt_to_python.python_to_pmt(value)
> b = pmt.pmt_to_python.pmt_to_python(a)
> print(b-value)
0.0
> print(f"{b-value:.50f}")
0.00000000000000000000000000000000000000000000000000

This is basically true for most floating point formats: The way a number is printed is not equal to the number itself!

PMT knows this and makes a decision to not try and represent many digits when printing – that's really more of a convenience function. When you need to work with the value of a PMT, you'd always convert that PMT to a native type again.

  • Related