URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9928
[ Назад ]

Исходное сообщение
"Логика"

Отправлено RedD , 26-Окт-14 21:04 
Есть 16 -ти битное число типа, 0x0000 h, как его разбить на 0x00h H, 0x00h L.

Содержание

Сообщения в этом обсуждении
"Логика"
Отправлено RedD , 26-Окт-14 22:33 
Data 16 bit
usignet char Н равно data // младший
L равно data/256 //старший


Так?



"Логика"
Отправлено RedD , 26-Окт-14 22:38 
Тьфу l с h попутал, ну главное принцып

"Логика"
Отправлено RedD , 26-Окт-14 22:56 
Лана проверил, работает, вопрос закрыт )



"Логика"
Отправлено RedD , 26-Окт-14 23:06 
int data=0xFCFC;
usignet char L=0;
usignet char H=0;
L=data;            //FC
H=data/256Dec;     //FC

"Логика"
Отправлено Alex_S , 27-Окт-14 08:06 
> int data=0xFCFC;
> usignet char L=0;
> usignet char H=0;
> L=data;            
> //FC
> H=data/256Dec;     //FC

  да хрен то
аспект порядка байт не рассмотрен
может быть наоборот, первый байт - старший

но для школы - сойдет



"Логика"
Отправлено RedD , 27-Окт-14 08:15 
>> int data=0xFCFC;
>> usignet char L=0;
>> usignet char H=0;
>> L=data;
>> //FC
>> H=data/256Dec;     //FC
>   да хрен то
>  аспект порядка байт не рассмотрен
>  может быть наоборот, первый байт - старший
>  но для школы - сойдет

НО НО, я целый час думал, 20 минут в нете рылся )))))))))))


"Логика"
Отправлено RedD , 27-Окт-14 08:17 
>[оверквотинг удален]
>>> usignet char L=0;
>>> usignet char H=0;
>>> L=data;
>>> //FC
>>> H=data/256Dec;     //FC
>>   да хрен то
>>  аспект порядка байт не рассмотрен
>>  может быть наоборот, первый байт - старший
>>  но для школы - сойдет
> НО НО, я целый час думал, 20 минут в нете рылся )))))))))))

А вообще не для школы, в atmegе32 нужно так разбить, чтоб на два разных порта выдать )


"Логика"
Отправлено name , 27-Окт-14 14:49 
про операции сдвига вправо влево не слышали?

"Логика"
Отправлено RedD , 27-Окт-14 17:47 
> про операции сдвига вправо влево не слышали?

Слышал, имеете ввиду
H=data>>8;
L=(data<<8)>>8; вначале старший в нули выдвигаем,

Так ?



"Логика"
Отправлено RedD , 27-Окт-14 17:51 
H=data>>8;
L=data; старший сам отвалится

"Логика"
Отправлено pavlinux , 29-Окт-14 20:04 
> Есть 16 -ти битное число типа, 0x0000 h, как его разбить на
> 0x00h H, 0x00h L.

H = data^0x00ff;
L = data^0xff00;


"Логика"
Отправлено RedD , 03-Ноя-14 03:40 
Для Павлиналинукса

H = data^0x00ff;
L = data^0xff00;

Вот это похоже то что нужно,



"Логика"
Отправлено skb7 , 04-Ноя-14 00:48 
> Для Павлиналинукса
> H = data^0x00ff;
> L = data^0xff00;
> Вот это похоже то что нужно,

Не слушайте злого дядю, операция "исключающего или" здесь вообще никаким боком. Правильный ответ уже был озвучен:


h = data >> 8;
l = data;

Так же нужно учитывать порядок байт. Процессор атмеги вроде little-endian, так что этот код будет корректен. Но если данные пришли по сети -- там big-endian, и всё будет наоборот. Так же надо учитывать вопрос портируемости -- если код пишется для одного проца -- можно и так. Если надо будет портировать -- то нужно делать проверку на endianness.


"Логика"
Отправлено pavlinux , 04-Ноя-14 01:12 
>> Для Павлиналинукса
>> H = data^0x00ff;
>> L = data^0xff00;
>> Вот это похоже то что нужно,
> Не слушайте злого дядю

Сам боклан :-P  

Время дофига? Напиши молекулярный извлекатель для всех битностей от 8 до 128,
На входе число, на выходе два, в двое меньшей битности.

P.S. case, typeof - для дефочек, только битовые операции, только хардкор!


"Логика"
Отправлено skb7 , 04-Ноя-14 21:24 
> Сам боклан :-P

Як той казав: "я мненью вашему вращенье придавал, и осью был мой детородный орган" :)

> Время дофига? Напиши молекулярный извлекатель

Сударь, судя по вашем ухищрениям с компиляцией /dev/null, время дофига как раз-таки у вас. Just saying.


"Логика"
Отправлено pavlinux , 04-Ноя-14 00:58 
> Для Павлиналинукса
> H = data^0x00ff;
> L = data^0xff00;
> Вот это похоже то что нужно,

Тут одно НО, если у тебе нужны не просто старшая и младшая половины, а
нужно запихнуть результат в, действительно, 8-битную переменную, то
компилятор сам урежет старшие байты. То есть строка L = data^0xff00
будет одно и тоже, что и L = data^0x00 или тупа L = data;  

Например:

int data = 0xbeaf;
unsigned char H = data^0x00ff;
unsigned char L = data^0xff00;

L = 0xaf
H = (0xbeaf ^ 0x00ff) => (0xaf ^ 0xff) => (0xa0 ^ 0xf0) => f-a вроде 0x50;

---
Поэтому для примера выше можно так:

unsigned char H = ((data >> 8)|( data << 8));
unsigned char L = data;


"Логика"
Отправлено RedD , 04-Ноя-14 06:55 
Вот злодеи ...
Лана понял что своей башкой думать нада, предварительно всех послушав.

А вот так мне тож больше нравится,

H=data>>8;
L=data;

Хотя и остальное опробую время будет, отпишусь )
Не могу с мобилки писать, издевательство какое то, толи дело стандартная клава писишная ...


"Логика"
Отправлено RedD , 04-Ноя-14 07:13 
Для skb7 я тебя понял ..., спасибо )

"Логика"
Отправлено RedD , 04-Ноя-14 07:21 
А насчет порядка бит, я если честно только с AVR ками, и то так мелочевка, для себя ...
И только под конкретную задачу, нужно мне было, я сделал, и забыл, я не профи в этом плане, я инженер )

Но я учусь )



"Логика"
Отправлено RedD , 04-Ноя-14 08:04 
H = data^0x00ff;
L = data^0xff00;

Вот это кстати не работает ) Павлинус тя точно нельзя слушать, но да лана умнее буду )
Но у меня есть маленькое преимущество, я сразу в железе делаю, и если код не работает это сразу видно ))))


"Логика"
Отправлено skb7 , 04-Ноя-14 15:46 
> H = data^0x00ff;
> L = data^0xff00;
> Вот это кстати не работает ) Павлинус тя точно нельзя слушать, но
> да лана умнее буду )
> Но у меня есть маленькое преимущество, я сразу в железе делаю, и
> если код не работает это сразу видно ))))

А оно и не может работать, маски накладываются операцией "побитовое И", т.е. "&", а точно не операцией "побитовое исключающее ИЛИ". Посмотрите в википедии таблицы истинности для этих операций и всё станет понятно. pavlinux либо опечатался, либо специально троллит (никогда не знаешь, он одинаково часто проделывает и то, и другое).


"Логика"
Отправлено RedD , 04-Ноя-14 19:00 
>[оверквотинг удален]
>> L = data^0xff00;
>> Вот это кстати не работает ) Павлинус тя точно нельзя слушать, но
>> да лана умнее буду )
>> Но у меня есть маленькое преимущество, я сразу в железе делаю, и
>> если код не работает это сразу видно ))))
> А оно и не может работать, маски накладываются операцией "побитовое И", т.е.
> "&", а точно не операцией "побитовое исключающее ИЛИ". Посмотрите в википедии
> таблицы истинности для этих операций и всё станет понятно. pavlinux либо
> опечатался, либо специально троллит (никогда не знаешь, он одинаково часто проделывает
> и то, и другое).

Обьясни у каждого .h файла есть .c
Или бывает так что .h есть,  а .c нет?
то что .c может быть без .h понятно


"Логика"
Отправлено skb7 , 04-Ноя-14 19:58 
> Обьясни у каждого .h файла есть .c
> Или бывает так что .h есть,  а .c нет?
> то что .c может быть без .h понятно

Компилируется именно .c файл (в объектный файл), .h файл не компилируется. Перед этапом компиляции запускается препроцессор и просто заменяет все строки "#include" содержимым указанного .h файла.

Так что да, может быть .h без соответствующего .c файла. Например, у тебя есть разные модули (.c файлы): модуль для датчика температуры, модуль для общения с дисплеем, модуль для общения с микросхемой RTC и т.д. Во всех модулях тебе нужно получать нижний и верхний байт от двухбайтной переменной. Можно сделать хедер, назвать его например "common.h":


#ifndef COMMON_H
#define COMMON_H

#include <stdint.h>

/* Routines to get the high and low byte of 16-bit word */
#define HI(x) ((uint8_t)(x >> 8))
#define LO(x) ((uint8_t)(x))

#endif /* COMMON_H */

Дальше в каждом модуле подключить этот хедер и использовать макросы из него. При это не будет никакого "common.c" файла и всё будет работать.

На самом деле в .h файлы обычно засовывают две вещи:
1. объявления функций какого-то .c файла, т.е. интерфейс этого .c файла (чтобы другие .c файлы могли юзать эти функции подключая этот хедер)
2. всякие макросы, которые могут использованы разными модулями (.c файлами)

В свою очередь без .h файла тоже можно обойтись -- просто скопировать руками содержимое .h файла вместо соответствующей строки #include.


"Логика"
Отправлено pavlinux , 04-Ноя-14 20:11 
>> Обьясни у каждого .h файла есть .c
>> Или бывает так что .h есть,  а .c нет?
>> то что .c может быть без .h понятно
> Компилируется именно .c файл (в объектный файл), .h файл не компилируется.

Придумаешь тоже! Ни .с, ни .h не компилируются!!!

$ echo 'int main(){ return 0;}' > system32.dll
$ gcc -xc system32.dll
$ ./a.out

$ gcc -xc /dev/null -c
$ objdump -d null.o

objdump -d null.o

null.o:     формат файла elf64-x86-64

Гы :)


"Логика"
Отправлено skb7 , 04-Ноя-14 21:13 
> Придумаешь тоже! Ни .с, ни .h не компилируются!!!

С точностью до наоборот. Существующая возможность принудительно задавать тип файла через опцию "-x" не отменяет того факта, что и .c, и .h компилируются. По умолчанию компилятор определяет тип файла как раз таки по расширению). Из "man gcc":


-x none
         Turn off any specification of a language, so that subsequent files are handled according to their file name suffixes (as they are if -x has not been used at all).

Да, и раз уж на то пошло, то даже .h можно компилировать, см. Precompiled headers: https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html

А .c можно не компилировать напрямую, а например инклудить в другие .c файлы; см. например вывод следующей команды в каталоге с сырцами кернела:


grep -r 'include ".*\.c"' drivers/usb/*

Вот тут объяснено зачем это может понадобиться:
http://stackoverflow.com/questions/232693/including-one-c-so...

В конечном итоге всё сводится к пониманию простых вещей, описанных в стандарте и в "man gcc":

1. процесс сборки: препроцессинг (*.c, *.h -> *.c), компиляция (*.c -> *.S), ассемблирование (*.S -> *.o), компоновка (*.o -> бинарь)
2. для сборки программы необходимо и достаточно чтобы был один .c-файл с одной функцией с именем main(), которая будет являться точкой входа программы.

> $ echo 'int main(){ return 0;}' > system32.dll
> $ gcc -xc system32.dll
> $ ./a.out

Ты прямо указываешь компилятору, что "трактуй этот файл как .c", т.е. ты свой файл обозвал .c, только неявно.

По умолчанию gcc определяет тип файла по его расширению, а значит компилируются всё же .c файл.

> $ gcc -xc /dev/null -c
> $ objdump -d null.o
> objdump -d null.o
> null.o:     формат файла elf64-x86-64
> Гы :)

Да, пустой файл можно скомпилировать (правда особого смысла в этом нет).


"Логика"
Отправлено pavlinux , 05-Ноя-14 18:58 
> Да, пустой файл можно скомпилировать (правда особого смысла в этом нет).

Процессор погреть, холода скоро.



"Логика"
Отправлено skb7 , 04-Ноя-14 15:42 
> А насчет порядка бит, я если честно только с AVR ками, и то так мелочевка, для себя ...

Только порядок байт (в машинном слове), а не бит (в байте)  ;)
Ну если только AVR -- то там little-endian (как на PC) и можно не париться.

> я сделал, и забыл, я не профи в этом плане, я инженер )

Я тоже инженер. Но в низкоуровневом программировании (работа с железом) такие вещи постоянно применяются (сдвиги, маски, endianness, указатели), так что лучше не забывать.


"Логика"
Отправлено RedD , 04-Ноя-14 09:07 
Своей башкой думать и смотреть исходники линуксовые там все есть уже давно )
Митрофаныч прав )

"Логика"
Отправлено pavlinux , 04-Ноя-14 15:45 
> А вот так мне тож больше нравится,
> H=data>>8;

unsigned char H = ((data >> 8)|( data << 8));

Это преобразование из Little Endian в Big Endian,
с последующих отрезанием старшей части компилятором.


"Логика"
Отправлено RedD , 11-Ноя-14 12:09 
>> А вот так мне тож больше нравится,
>> H=data>>8;
> unsigned char H = ((data >> 8)|( data << 8));
> Это преобразование из Little Endian в Big Endian,
> с последующих отрезанием старшей части компилятором.

Почему не работает функция ceil, библиотека math.h подключена


"Логика"
Отправлено skb7 , 11-Ноя-14 14:50 
>>> А вот так мне тож больше нравится,
>>> H=data>>8;
>> unsigned char H = ((data >> 8)|( data << 8));
>> Это преобразование из Little Endian в Big Endian,
>> с последующих отрезанием старшей части компилятором.
> Почему не работает функция ceil, библиотека math.h подключена

Ответ как всегда в начале мана:


$ man 3 ceil

Видим следующее:


NAME
       ceil, ceilf, ceill - ceiling function: smallest integral value not less than argument

SYNOPSIS
       #include <math.h>

       double ceil(double x);
       float ceilf(float x);
       long double ceill(long double x);

       Link with -lm.

Т.е. одно из двух:
1. либо вы не линкуетесь с libm.so
2. либо вы используете неправильные типы данных:

Вот пример работающего кода:


#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    double x = 15.365;

    printf("x       = %f\n", x);
    printf("ceil(x) = %f\n", ceil(x));

    return EXIT_SUCCESS;
}

Собираем с линковкой libm.so:


$ gcc main.c -lm

Вывод:


x       = 15.365000
ceil(x) = 16.000000


"Логика"
Отправлено pavlinux , 27-Ноя-14 01:58 
> Почему не работает функция ceil, библиотека math.h подключена

Зачем math.h?

#include <stdio.h>
#define ceil(x) (long long)(x+1)

int main(void)
{
    double x = 987.654321;
    printf("%lld\n", ceil(x));
    return 0;
}


:)