float型をchar型にして送信する…(C言語)

float型のデータ(32bit)をchar型(8bit)のデータしかやり取りできない通路を使って送受信できないか?と聞かれたので,適当に作ってみた.

C言語のfloat値のビットを表示する - はこべにっき ♨に,float型のデータをbit列にするコードがあったので,後はこれに,8bitずつに切り分けて格納する部分と,8bitずつに切り分けてあるものをつなぎ合わせてfloat型に戻してやる部分を実装してみた.

出力結果

出力結果はこんな感じになります.(18.21983をコマンドラインから引数として渡した場合)

$ ./a 18.21983
入力されたfloat:target = 18.219830
float型の中身(bit列):01000001100100011100001000110110
 floatの中身をint型として理解する:1100071478
先ほどint型とした中身(bit列):01000001100100011100001000110110
8bitずつに区切って,int型にぶち込む:

x1=65
x2=145
x3=194
x4=54

これらをchar型に変換する
c1=A
c2=
c3=ツ
c4=6

再びchar型をint型に戻す
y1=65
y2=145
y3=194
y4=54

4つ分割されていたものを合わせる
1100071478
最終的に元に戻る: 18.219830


(1349.389を引数として渡した場合)

$ ./a 1349.389
入力されたfloat:target = 1349.389038
float型の中身(bit列):01000100101010001010110001110011
 floatの中身をint型として理解する:1151904883
先ほどint型とした中身(bit列):01000100101010001010110001110011
8bitずつに区切って,int型にぶち込む:

x1=68
x2=168
x3=172
x4=115

これらをchar型に変換する
c1=D
c2=ィ
c3=ャ
c4=s

再びchar型をint型に戻す
y1=68
y2=168
y3=172
y4=115

4つ分割されていたものを合わせる
1151904883
最終的に元に戻る: 1349.389038

ソースコード

ソースコードはこんな感じ

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

union IntAndFloat {
    int ival;
    float fval;
};

union newFloat {
    int ival;
    float fval;
};


int main (int argc, char *argv[]) {
    int c=0;
    int i = 0;
    
    int buf=0;
    unsigned int x1=0,x2=0,x3=0,x4=0;//分割
    
    unsigned char c1,c2,c3,c4;//char型に変換
    
    unsigned int y1=0,y2=0,y3=0,y4=0;//intに戻す
    
    
    unsigned int ne=0;//くっつける
    
    
    /////////本文スタート/////////
    union IntAndFloat target;
    target.fval = atof(argv[1]);
    
    printf("入力されたfloat:target = %f\n", target.fval);
    printf("float型の中身(bit列):");
    for (i = 0; i < 32; i++) {
        if ( (target.ival & 0x80000000) == 0x80000000) {
            printf("1");
            c = (c<<1);
            c = c+1;
        }
        else {
            printf("0");
            c = (c<<1);
        }
        target.ival = target.ival << 1;
    }
    printf("\n floatの中身をint型として理解する:");
    printf("%d\n",c);
    buf = c;
    printf("先ほどint型とした中身(bit列):");
    for (i = 0; i < 32; i++) {
        if ( (c & 0x80000000) == 0x80000000) {
            printf("1");
        }
        else {
            printf("0");
        }
        c = c << 1;
    }
    
    printf("\n8bitずつに区切って,int型にぶち込む:\n");
    printf("\n");
    x1 = buf>>24;
    printf("x1=%d\n",x1);
    
    x2 = buf<<8;
    x2 = x2 >>24;
    printf("x2=%d\n",x2);
    
    x3 = buf<<16;
    x3 = x3 >>24;
    printf("x3=%d\n",x3);
    
    x4 = buf<<24;
    x4 = x4 >>24;
    printf("x4=%d\n",x4);
    
    printf("\nこれらをchar型に変換する\n");
    c1 = (char) x1;
    c2 = (char) x2;
    c3 = (char) x3;
    c4 = (char) x4;
    
    printf("c1=%c\n",c1);
    printf("c2=%c\n",c2);
    printf("c3=%c\n",c3);
    printf("c4=%c\n",c4);
    
    printf("\n再びchar型をint型に戻す\n");
    y1 = c1;
    y2 = c2;
    y3 = c3;
    y4 = c4;
    
    printf("y1=%d\n",y1);
    printf("y2=%d\n",y2);
    printf("y3=%d\n",y3);
    printf("y4=%d\n",y4);
    
    printf("\n4つ分割されていたものを合わせる\n");
    ne = ne + (y1<<24);
    ne = ne + (y2<<16);
    ne = ne + (y3<<8);
    ne = ne + (y4);
    
    printf("%d\n",ne);
    
    union newFloat newtarget;
    newtarget.ival = ne;
    
    printf("最終的に元に戻る: %f\n", newtarget.fval);



    return 0;
}

雑感

http://www.geocities.jp/ky_webid/c/047.html
共用体とは、2つ以上の変数が、同じメモリ領域を共有するという構造のこと です。共用体は、unionというキーワードを使って、次のように宣言します。列挙 型と同じく、やはり構造体宣言と似ています。

おお,便利ですね!!(知らなかった俺バカ?)