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.