реклама на сайте
подробности

 
 
> Как разобрать float на байты в pythone, Или подскажите алгоритм на С
mempfis_
сообщение Feb 20 2009, 12:32
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Добрый день.
Стоит задача разобрать float-число на байты и выполнить побайтную пересылку с помощью gprs-модема.
Задача осложнена тем что пишу на python-е и стандартный модуль struct, способный выполнить эту задачу, модемом не поддерживается.

Поэтому прошу помочь алгоритмом преобразования строки содержащей float-число в 4 байта этого самого float-числа.

Т.е. параметр будет строка вида '0012.5000' а результат 11000001 01001000 00000000 00000000b = C1 48 00 00h

Саму строку легко могу разбить на отдельные числа. А вот собрать с них float проблематично.
Подскажите пожалуйста где об этом можно почитать, может быть есть готовые алгоритмы на С (т.к. сомневаюсь что они есть на pythone)
Заранее спасибо за помощь smile.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ukpyr
сообщение Feb 21 2009, 11:39
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



что-то типа :
Код
f = float('0012.5000')
bytes = struct.pack('f', f)
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Feb 21 2009, 22:31
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(ukpyr @ Feb 21 2009, 14:39) *
что-то типа :
Код
f = float('0012.5000')
bytes = struct.pack('f', f)


Да этот модуль мне подходит но он не поддерживается интерпретатором питона gprs-модема (я об этом написал в самом первом посте это и послужило поводом для создания темы) crying.gif

Мне нужен пример на С или питоне для перевода строки в число типа float одинарной точности чтобы я мог его переделать в свою функцию которая могла бы вернуть мне 4 байта этого float-числа. Или хотябы понятное описание алгоритма перпевода десятичных дробных чисел в float. smile.gif
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Feb 22 2009, 00:36
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Что-то типа такого?

data = pack('F', 1.0)

f = unpack('F', data[0:4])
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Feb 23 2009, 10:59
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Ну вот разобрался в преобразовании чисел во float и написал свой скрипт на питоне для перевода строки 'xxxx.yyyy' в 4 байта соответствующие float-числу одинарной точности.
Для контроля правильности преобразования использовал функцию pack из модуля struct.
Может кто что посоветует в плане оптимизации.
Функция принимает строку - знак, 4-5 знаков целой части, 4-5 знаков дробной части, переводит их в 4 байта и возвращает их.
Обработку ошибок не провожу.
Вобщем буду благодарен любой критике smile.gif

P.S. Для тех кто захочет сказать 'А нафиг это надо если есть модуль struct' ещё раз повторяю ИНТЕРПРЕТАТОР ПИТОНА GPRS-МОДЕМА НЕ ПОДДЕРЖИВАЕТ МОДУЛЬ STRUCT (в отличии от компилятора О_о )

CODE
import struct

def strToFloat(string):
#для контроля преобразования строки во флоат используем функци. pack из модуля struct
res = struct.pack('f', float(string))
dd3 = hex(ord(res[3]))
dd2 = hex(ord(res[2]))
dd1 = hex(ord(res[1]))
dd0 = hex(ord(res[0]))
#print dd3, dd2, dd1, dd0

#ищем указатели на знак и точку
psighn = string.find('-')
ppoint = string.find('.')

#определяем знак мантиссы, выделяем целу. и дробну. часть
sighn = 0
integer = 0
fract = 0
if(psighn != -1):
sighn = 1
integer = string[1:ppoint]
else:
integer = string[:ppoint]
fract = string[ppoint+1:]+'0'
#print 'integer=', integer
#print 'fract=', fract


#определяем сколько бит занимает целая часть числа
int_data = int(integer, 10)
int_bit = 0
mask = 0x800000
if(int_data > 0):
for int_bit in range(0,24,1):
if((int_data & mask) == 0):
mask = mask >> 1

else:
int_bit = 23 - int_bit
#print 'MSB position =',int_bit
break

#print 'num of bits=',int_bit

#формируем смещённый показатель степени и добавляем его до флоат-числа
power = 127 + int_bit
#print 'power=',power
float_data = (power<<23)
#print 'float_data=',hex(float_data),'\n'

#добавляем до флоат-числа целу. часть без старшего единичного бита
#зануляем старший бит
temp = int_data&(~(2**int_bit))
#print temp
#добавляем целу. часть
float_data = float_data | (temp*(2**(23-int_bit)))
#print float_data

#определяем сколько бит осталось для дробной части
fract_bit = 23-int_bit
#print fract_bit

#само дробное число
fract_data = int(fract, 10)
#print fract_data

#определяем порядок числа
val = 0
if((fract_data > 0) and (fract_data <= 10)):
val = 10
elif((fract_data > 10) and (fract_data <= 100)):
val = 100
elif((fract_data > 100) and (fract_data <= 1000)):
val = 1000
elif((fract_data > 1000) and (fract_data <= 10000)):
val = 10000
elif((fract_data > 10000) and (fract_data <= 100000)):
val = 100000
#print val

#формируем дробну. часть числа
fract_float = 0
for k in range(0,fract_bit,1):
fract_data = fract_data*2
fract_float = fract_float << 1
if(fract_data >= val):
fract_data = fract_data-val
fract_float = fract_float|0x1
#print k
#print hex(fract_float)
#print fract_float

fract_data = fract_data*2
if(fract_data >= val):
fract_float = fract_float|0x1

#присоединяем дробну. часть к всему числу
float_data = float_data|fract_float
#print float_data
result=[0,0,0,0]
result[3]=0
if(sighn == 1):
result[3] = 0x80
result[3] = result[3]|(float_data>>24)&0xff
result[2] = (float_data>>16)&0xff
result[1] = (float_data>>8)&0xff
result[0] = (float_data)&0xff

print '\nethalon=', dd3, dd2, dd1, dd0
print 'my func=', hex(result[3]),hex(result[2]),hex(result[1]),hex(result[0])
return result

strToFloat('-25123.456')
strToFloat('1025.23')
trToFloat('36511.99')
strToFloat('23999.9988')
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 21:34
Рейтинг@Mail.ru


Страница сгенерированна за 0.01378 секунд с 7
ELECTRONIX ©2004-2016