float를 char배열에 담기

paeksj98의 이미지

펌웨어 시리얼 통신 하는걸 만드는데...

생각같이 안되네요.

혹시 float를 char[4]에 담는 좋은 방법좀 알고 싶습니다.

최종 만드는게 char[255]에 float, unsigned char로된 데이터들을 채워서 보내려고 하는데...

생각같이 잘안되네요.

이런거에 막히면 갑갑하네요....

liveeasily의 이미지

저도 괜시리 궁금해집니다..

neon20의 이미지

구현하시는 형태가 혹시 이것인가요?

char buffer[256];
void *p;

p = buffer;

*(float *)p = ?????;
p = p + (sizeof(float));

*(unsigned char *)p = ???;
p = p + (sizeof(unsigned char))

paeksj98의 이미지

p = p + (sizeof(float));

이부분에서 에러를 배터 내네요.. 제가 보기에는 아무 문제가 없어 보이는데...

expression must be a pointer to a complete object type

paeksj98의 이미지

p = p + (sizeof(float));

이부분에서

p = (float *)p + (sizeof(float));

(float *)이걸 추가해줘야 하네요.

감사합니다.

bushi의 이미지

틀렸습니다.
애초에 에러는 (void*) 에 대한 + 연산을 할 수 없기 때문이었습니다. 대상체의 크기를 알수 없으므로 unit 연산이 불가능하기 때문입니다.
(float *)p + 1 을 하시던가 (char *)p + sizeof(float) 을 하셔야 합니다.
전자는 위험하니 ... 애시당초
char *p;
처럼 정의하시면 적어도 헷갈리진 않습니다.

unsigned char buf1[64];
unsigned char buf2[sizeof(float)];
 
float *p1 = (float *)&buf1[1];
float *p2 = (float *)&buf2[0];
*p1 = *p2 = 3.14f;
printf(" %x %x %x %x\n", buf1[1], buf1[2], buf1[3], buf1[4]);
printf(" %x %x %x %x\n", buf2[0], buf2[1], buf2[2], buf2[3]);
그 기계에서 이 코드가 이상한 결과를 뱉어낸다면, 작성하신 코드를 전반적으로 수정하셔야 할 겁니다.

OTL

tj의 이미지

그 방향으로는 얼라인먼트에 문제가 생깁니다. buf1/2 얼라인먼트를 강제로 정해주거나 float을 변수로 쓰고 주소를 char *로 캐스팅을 하는 게 좋습니다.

bushi의 이미지

제 말이 그말입니다.

OTL

tj의 이미지

ㅎㅎ 그런가요. 뭔가 점점 난독 증세가 심해지는 거 같아요.

Scarecrow의 이미지

이런건 union으로 짜는게 더 가독성이 있고 쉬울듯 합니다.

paeksj98의 이미지

주조값이 제대로 점프가 안되서 (char *)p + sizeof(float)이렇게 했었는데...

가만 보니 bushi님이 알려주신 char*로 선언하니 한결 코드가 낳아졌네요....^^

union은 책에서 보기는 했었는데 실제로 이런경우 적용하면 뭐가 좋은지 모르겠는데 간단한 설명좀 부탁드려도 될런지...

소타의 이미지

struct {
float
unsigned char
등등등 총 255바이트의 데이터
} __패딩고려하던지팩시켜야겠죠?

union {
위의struct
char[255]
}

이렇게 하면 이 union은 255바이트입니다.
개발할 때는 union내의 struct 구조를 맘대로 사용하고 전송할 때는 union내의 char[255]를 전송하면 됩니다.
같은 메모리 내용을 다른 표현을 하는 것 뿐입니다.

unsouled의 이미지

간단하게 코드로 설명하자면..

#include <stdio.h>
 
typedef union
{
  unsigned char a[4];
  float b;
} union_data;
 
int main()
{
  union_data data;
  data.b = 1.234;
  printf("%x %x %x %x\n", data.a[0], data.a[1], data.a[2], data.a[3]);
  printf("%f\n", data.b);
  return 0;
}

메모리를 공유하니, float 로 넣고 char 로 빼낼 수 있죠.

vacancy의 이미지


union이 가장 나은 방법이겠지만,

char cbuf[..];
float *fbuf = cbuf;
 
fbuf[0] = ..
fbuf[1] = ..
:
send(.., cbuf, ..)

이렇게 하는 것도 방법일 것 같네요.

neogeo의 이미지

위에 나온 이야기들에 추가로 노파심에 말씀드리자면,

시리얼 통신이 이기종 간이라면 엔디안도 잘 맞춰주셔야 합니다.

Neogeo - Future is Now.

Neogeo - Future is Now.

minonnet의 이미지

RS232로 통신을 한다면, 통신 프로토콜까지 고려해야 하는데요.
float을 char로 변환해서 그냥 1바이트씩 실어보내는 것을 에러가 발생할 수 있습니다.
예를 들어, STX를 0x02, ETX를 0x03로 잡았을 때, (<-- 보통 이렇게 잡으니까요)
통신 패킷의 구성을 다음과 같이 구성하였을 때,
| STX | LEN | CMD | 보내려는데이터 | CHKSUM | ETX |
이러했을 때, 불행하게도 보내려는데이터의 한 바이트가 0x03일때는
데이터를 제대로 전송하기가 쉽지 않을 것입니다.
따라서 저는 float를 string으로 변환해서 전송하고
받는 쪽에서 다시 string을 float으로 변환해 주는 방법을 추천드립니다.

jj의 이미지

이기종간에 문제점이 도사리기때문에...

필요한 resolution에 따라, 1.123 => 1123, 11.23 => 11230 이런식으로 사용하는것도 한 방법인듯;;

--
Life is short. damn short...

--
Life is short. damn short...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.