Нахождение обратной функции, которая преобразует 16-разрядное целое число без знака в double

#c #integer #double #type-conversion #16-bit

#c #целое #double #преобразование типа #16-разрядный

Вопрос:

У меня есть функция, которая принимает 16-битное целое число без знака и преобразует его в double . Данные поступают от датчика температуры (MCP9808), и функция преобразует их в градусы Цельсия.

Функция определяется следующим образом:

 double convert_tempc(uint16_t data) {
    double temp = data amp; 0x0FFF;
    temp /=  16.0;
    if (data amp; 0x1000) temp -= 256;
    return temp;
} 
  

Мой вопрос в том, как я могу выполнить обратное этой серии операций?

Мне нужна функция для нахождения 16-битного значения, создаваемого этим датчиком, которое приводит к заданной температуре в градусах Цельсия.

Поскольку 16-разрядное значение может представлять только конечное число значений, я полагаю, что обратной функции потребуется найти ближайший double, который может быть представлен, а затем выполнить обратное преобразование.

Есть ли какой-нибудь простой способ сделать это?

Функция написана на C, но я буду реализовывать ее на Python.

Комментарии:

1. «Функция написана на C, но я буду реализовывать ее на Python». Что ж, удачи, тогда сделайте это и спросите еще раз, если у вас возникли конкретные проблемы с этим. 16-разрядное целое число по-прежнему является целым числом, только с ограниченным максимальным значением. В чем ваш вопрос?

2. Я не спрашиваю о преобразовании функции в python, я спрашиваю о нахождении серии операций, которые выполняли бы функциональную инверсию (возьмите double, выплюните uint16_t). Я не беспокоюсь о преобразовании c в python.

3. Вы имеете в виду изменение операторов? -= соответствует = , /= соответствует *= ; побитовые операции просто проверяют диапазоны, но с потерями, поэтому вы все равно не можете быть точными. В основном просто применяйте операторы наоборот. int(temp * 16) amp; 0xFFFF должно сделать.

4. Строго говоря, эта функция не обратима, потому что она теряет 3 самых значимых бита data . Однако, если вас не волнуют эти биты, или датчик возвращает данные только в диапазоне 0 <= data <= 0x1fff , тогда инвертировать функцию просто.

5. @MisterMiyagi: это неправильно обрабатывает знаковый бит. Но int(temp * 16) amp; 0x1FFF выглядит довольно неплохо. 🙂

Ответ №1:

Вот некоторый код, который проверяет формулу, предложенную в комментариях.

 def u16_to_float(data):
    temp = data amp; 0x0FFF
    temp /=  16.0
    if data amp; 0x1000:
        temp -= 256
    return temp

def float_to_u16(temp):
    return int(temp * 16) amp; 0x1FFF

# test

for data in range(0x2000):
    temp = u16_to_float(data)
    u = float_to_u16(temp)
    assert u == data, (data, temp, u)

print('Ok')