Найти - Пользователи
Полная версия: Чтение modbus RTU запроса python 1.5
Начало » Mobile Python » Чтение modbus RTU запроса python 1.5
1 2 3 4
PooH
У меня для вас плохие новости, страница пять руководства: Floating point numbers are not supported.
Этот огрызок питона умеет только в целые числа. А что вы хотели сделать, может можно обойти?
vic57
при таком урезанном питоне можно только с костылями что-то придумать
 def bin2int(binstr):
# дробная часть 1/2 + 1/4 +1/8...
    l = (5000000,2500000,1250000,625000
         ,312500,156250,78125,39062,19531,9765)
    tmp = 0
    s  = min(len(binstr),len(l))
    for i in xrange(s):
        if binstr[i] == '1': tmp += l[i]
    # выравнивание до 7 разрядов
    return str(tmp).zfill(7)
    
def hex2float(hexstr):
    x = int(hexstr,16)
    sign = '-'
    if x & 0x80000000 == 0: sign = ''
    exp = ((x & 0x7f800000) >> 23 ) - 127
    mantiss = (x & 0x7fffff)
    index = 0x400000
    l = ''
    for i in xrange(23):
        if index & mantiss == 0: l +='0'
        else: l += '1'
        index >>= 1
    l = '1' + l   
    if exp >= 0:
        exp += 1
        l = l[:exp] + '.' + l[exp:]
    else:
        l = '0'*abs(exp) + l
        l = l[0] +'.' + l[1:]
    s = l.split('.')
    return sign + str(int(s[0],2)) + '.' + bin2int(s[1])
if __name__ == "__main__":
    #-1024.555
    num = 'c48011c3'
    print hex2float(num)
проверял по http://www.h-schmidt.net/FloatConverter/IEEE754.html
Svet
vic57
при таком урезанном питоне можно только с костылями что-то придумать
Спасибо за вариант решения
Но все равно не получилось
Кидает ошибку на строку x = int(hexstr,16)
 line 53, in hex2float
int() literal too large: c48011c3
PooH
Svet
Но все равно не получилось
И не получится, я же писал выше: то что на этой железке называют питоном не умеет в числа с плавающей запятой. Надо думать как обходить. Это зависит от того, что вы хотите делать с данными: если передать дальше, то может просто не трогать и отдать как есть, если отобразить, то конвертировать в строку. Если обрабатывать, то придется писать свой формат чисел. Что требуется то?

ЗЫ: невнимательно посмотрел, выше vic57 как раз в строку и конвертит
PooH
Svet
x = int(hexstr,16)
Попробуйте int заменить на long
vic57
да уж,засада
набери в консоли
 import sys
sys.maxint
и для проверки
 print int ('0xffff',16)
print int('0xffffffff',16)
print int('0b11111111111111111111111111111111',2)
походу такой питон на вычисления не заточен, только на прием-отправку сообщений(байтов)
vic57
попробуй такой вариант
 def bin2int(binstr):
# дробная часть 1/2 + 1/4 + 1/8 + 1/16...
    x = 50000000
    tmp = 0
    for i in xrange(len(binstr)):
        if binstr[i] == '1': tmp += x
        x >>= 1
    s = str(tmp)
    delta = 8 - len(s)
    if delta > 0: s = '0'*delta + s
    return s
def hex2bin(hexch):
    index = int(hexch,16)
    l = ('0000',
         '0001',
         '0010',
         '0011',
         '0100',
         '0101',
         '0110',
         '0111',
         '1000',
         '1001',
         '1010',
         '1011',
         '1100',
         '1101',
         '1110',
         '1111',
        )
    return l[index]
    
def hex2float(hexstr):
    binstr = ''
    for i in hexstr: binstr += hex2bin(i)
    sign = '-'
    if binstr[0] == '0': sign = ''
    expstr = binstr[1:9]
    mantiss = binstr[9:]
    mantiss = '1' + mantiss
    exp = int(expstr,2) - 127
    if exp >= 0:
        exp += 1
        mantiss = mantiss[:exp] + '.' + mantiss[exp:]
    else:
        mantiss = '0'*abs(exp) + mantiss
        mantiss = mantiss[0] +'.' + mantiss[1:]
    s = mantiss.split('.')
    return sign + str(int(s[0],2)) + '.' + bin2int(s[1])
if __name__ == "__main__":
    s ='41eee135'
    print hex2float(s)
    
Svet
Попробовал последний предложенный код. Выдает ошибку:
 Traceback (innermost last):
  File "\main.py", line 81, in ?
  File "\main.py", line 76, in hex2float
  File "\main.py", line 37, in bin2int zfillbuteError

81 строка это = print hex2float(s)
76 строка это = return sign + str(int(s,2)) + ‘.’ + bin2int(s)
37 строка это = return str(tmp).zfill(8)

Пробовал сделать print int ('0xffff',16) = выполнил, ответ 65535
Пробовал сделать print int('0xffffffff',16) = выполнил, ошибка int() literal too large: 0xffffffff
Пробовал сделать print int('0b11111111111111111111111111111111',2) = выполнил, ошибка invalid literal for int(): 0b11111111111111111111111111111111
vic57
sys.maxint? не пойму что за питон такой, стандартные функции не выполняются
vic57
код упростил, пробуй
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB