[轉]浮點轉字串的寫法

浮點轉字串的寫法

更改我的閱讀文章字型大小大 小
作者 : witsh0928(doctor)
[ 貼文 26 | 人氣 2329 | 評價 30 | 評價/貼文 1.15 | 送出評價 2 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 04:15:52

我本身是做DSP方面的,要透過RS232將數值傳到PC端.,在程式撰寫上遇到問題需要大家的幫助,再RS232每次傳輸只能傳8 bit,而且限制只能傳字串,我有2組數據在DSP要傳到電腦,例如 0.151647 和0.163265,要先轉換才能透過RS232丟出去,而且只能用純C的語法,C++的語法再DSP的編譯器不支援,有誰能給我指教
我有試過數值程式10^6然後丟出→失敗不行用PC接收到的數據錯誤
還有試過itoa→DSP的編譯器不支援
還有試過fcvt→依舊失敗
有誰可以救救我

作者 : sms(光)
[ 貼文 56 | 人氣 1891 | 評價 220 | 評價/貼文 3.93 | 送出評價 3 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 04:23:57

哈哈哈!有點白痴的作法:
fprintf( str , “%f” , m_float );

作者 : elac(不是個東西)
[ 貼文 22 | 人氣 1782 | 評價 110 | 評價/貼文 5 | 送出評價 4 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 06:49:21

>我本身是做DSP方面的,要透過RS232將數值傳到PC端.,在程式撰寫上遇到問題需要大家的幫助,再RS232每次傳輸只能傳8 bit,而且限制只能傳字串,我有2組數據在DSP要傳到電腦,例如 0.151647 和0.163265,要先轉換才能透過RS232丟出去,而且只能用純C的語法,C++的語法再DSP的編譯器不支援,有誰能給我指教

你或許可以把float的資料一個byte一個byte地傳過去, 反正字串就再補個’’給它.
PC端接收到資料後再放到一個連續的區塊讓float的指標來指, 我覺得應該是OK的.
概念就像下列程式:

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

int main() {
   int size = sizeof(float);
   char tmpdata[size+1];
   char *pdata = &tmpdata[0];
   float *pf_transmit;
   float *pf_receive = malloc(size);

   float f1 = 0.151647;
   float f2 = 0.163265;

   pf_transmit = &f1;
   memcpy(pdata, (void*)pf_transmit, size);
   pdata[size] = ‘’;

   // send data through pdata …

   memcpy(pf_receive, (void*)pdata, size);
   printf(“f1 = %fn”, *pf_transmit);

   pf_transmit = &f2;
   memcpy(pdata, (void*)pf_transmit, size);
   pdata[size] = ‘’;

   // send data through pdata …

   memcpy(pf_receive, (void*)pdata, size);
   printf(“f2 = %fn”, *pf_transmit);
}

當然前提是你DSP和PC對於float的表示法必須是一致的才行. 還有要注意big-endian或
little-endian的問題. 

作者 : asaman(asaman99)
[ 貼文 4 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 07:42:06

我看過F&Q…也看過發言規則等等的…
我很想發文章討論我現在程式的問題…但我翻來翻去就是找不到”發表新文章”..只好靠回覆別人的文章來求救…

請好心的大哥教教我吧…為什麼我找不到方法發新文章???

作者 : anderson_fang(Anderson) UNIX/Linux優秀好手C++卓越專家貼文超過200則
[ 貼文 297 | 人氣 2 | 評價 3070 | 評價/貼文 10.34 | 送出評價 1 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 09:01:38

在 C++ 文章列表這頁的討論文章列之上應該有這行 :

頁次 1/245 , 共25846篇文章, 6114個主題 發表新文章 同主題閱讀 BBS一般閱讀

看到 “發表新文章” 了嗎?

不過我剛剛也沒看到
refresh 之後才看到 @_@

作者 : anderson_fang(Anderson) UNIX/Linux優秀好手C++卓越專家貼文超過200則
[ 貼文 297 | 人氣 2 | 評價 3070 | 評價/貼文 10.34 | 送出評價 1 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人witsh0928註記此篇回應為很有道理2005/4/21 下午 09:44:13

想確定一下傳輸容量限制是 8 bits 還是 8 bytes?
如果是你說的 8 bits (1 byte), 那應該一次只能傳一個 char 型態的資料才對?
如果是 8 bytes 才可以傳非空的字串

先假定是 8 bytes 好了
要將浮點數轉字串可利用 snprintf() function
itoa() 不是標準,不支援的應該的 :
    double d = 0.151647;
    char a[9];
    memset(a, 0, sizeof(a));
    snprintf(a, sizeof(a), “%f”, d);

但注意到 a 陣列大小為 9 了嗎?
那是因為你的這筆 0.151647 資料
這個轉成字串後的大小為 8 加上 ‘’
這樣就超過傳輸限制大小了
如果有傳送超過 8 bytes 資料的需求
你可能可以實作一個簡單的協定
例如發送端發送超過 8 bytes 的資料前第一筆資料前置一些符號
接收端看到這個符號後就不斷收資料直到 ‘’ 為止

作者 : asaman(asaman99)
[ 貼文 4 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 09:53:18

怪了!!!…我真的找不到那個發表新文章的按鍵…是不是有什麼莫名其妙的設定問題?..

還是我有什麼認證沒通過啊???

作者 : asaman(asaman99)
[ 貼文 4 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 09:58:14

C++ 討論區列表 Hi !! asaman99(asaman) 討論區快速選單

歡迎討論C++程式設計上的各類問題!! [ 討論區發言規則 ]
  頁次 1/1035 共25851篇文章 同主題閱讀 BBS一般閱讀 第一頁 上一頁 下一頁 最末頁  

以上就是我看到的畫面上端…我找不到”發表新文章”

作者 : anderson_fang(Anderson) UNIX/Linux優秀好手C++卓越專家貼文超過200則
[ 貼文 297 | 人氣 2 | 評價 3070 | 評價/貼文 10.34 | 送出評價 1 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 10:54:41

>C++ 討論區列表 Hi !! asaman99(asaman) 討論區快速選單
>
>
>歡迎討論C++程式設計上的各類問題!! [ 討論區發言規則 ]
> 頁次 1/1035 共25851篇文章 同主題閱讀 BBS一般閱讀 第一頁 上一頁 下一頁 最末頁  
>
>
>以上就是我看到的畫面上端…我找不到’發表新文章’

在這頁重新整理一次網頁 (F5) 看看

作者 : blacken(Blacken)
[ 貼文 4 | 人氣 4 | 評價 30 | 評價/貼文 7.5 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/21 下午 10:57:31

float flt = 0.151647;
char str[8];

sprintf(str, “%f”, flt);

這樣就能將浮點數轉成字串了

作者 : witsh0928(doctor)
[ 貼文 26 | 人氣 2329 | 評價 30 | 評價/貼文 1.15 | 送出評價 2 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/22 上午 12:42:31

感謝大家提供的方法,小弟會去好好去測試,希望能順利成功,大家給我的祝福吧!

作者 : cog(Cog) VC++卓越專家C++優秀好手貼文超過200則
[ 貼文 458 | 人氣 12 | 評價 3390 | 評價/貼文 7.4 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/22 上午 09:21:27

>C++ 討論區列表 Hi !! asaman99(asaman) 討論區快速選單
>歡迎討論C++程式設計上的各類問題!! [ 討論區發言規則 ]
> 頁次 1/1035 共25851篇文章 同主題閱讀 BBS一般閱讀 第一頁 上一頁 下一頁 最末頁
>以上就是我看到的畫面上端…我找不到’發表新文章’

先生!在這個C++討論區飄發表新文章,必要條件是你的發文數在3篇以上,所以在你發了三篇開怎麼發表新文章的問題後,你現在應該可以找得到”發表新文章”的選項了。

作者 : cog(Cog) VC++卓越專家C++優秀好手貼文超過200則
[ 貼文 458 | 人氣 12 | 評價 3390 | 評價/貼文 7.4 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/22 上午 09:32:22

>float flt = 0.151647;
>char str[8];
>
>sprintf(str, ‘%f’, flt);
>
>這樣就能將浮點數轉成字串了

依照浮點數的特性,還是建議sprintf(str, ‘%7f’, flt);在%f裡面在多設定一個width,避免程式笨笨的轉出太長的字串。至於為什麼是7不是8,因為字串最後還要留一個位置給放。

作者 : kwong(kwong) 貼文超過200則
[ 貼文 257 | 人氣 739 | 評價 260 | 評價/貼文 1.01 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/22 上午 10:36:31

我以前寫了不少類似的東西.
float f1 = 0.151647;
float f2 = 0.163265;

char pdata[256];
int data_len=0;

     pdata[data_len++]=STX; // START OF TEXT
     pdata[data_len++]=packet_len; // PACKET_LEN 總長

     pdata[data_len++]=sizeof(float); // 跟著有多少 byte
     memcpy(&pdata[data_len],&f1,sizeof(float));
     data_len+=sizeof(float);

     pdata[data_len++]=sizeof(float); // 跟著有多少 byte
     memcpy(&pdata[data_len],&f2,sizeof(float));
     data_len+=sizeof(float);

     pdata[data_len++]=CRC; // CHECK SUM
     pdata[data_len++]=ETX; // START OF TEXT

作者 : asaman(asaman99)
[ 貼文 4 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/22 下午 06:29:33

基本上…Anderson與cog兩位大哥的建議我都試過了….
只是還是沒解決…我在想我是不是要認命了…>_<

這跟解析度有關係嗎?……

作者 : chiuinan2(青衫)討論區板主 Visual C++ .NET卓越專家VC++一代宗師Visual Basic優秀好手資訊類作業求救卓越專家一般曠世奇才程式設計甘苦談優秀好手C++ Builder優秀好手上班族的哈拉園地優秀好手C++頂尖高手Assembly優秀好手貼文超過3000則人氣指數超過150000點
[ 貼文 3689 | 人氣 170106 | 評價 33890 | 評價/貼文 9.19 | 送出評價 124 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/22 下午 06:56:17

>基本上…Anderson與cog兩位大哥的建議我都試過了….
>只是還是沒解決…我在想我是不是要認命了…>_<
>這跟解析度有關係嗎?……

請參閱這一篇, 若仍有疑問可在該討論串回覆提出:

http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&board_pc2020=msgboard&index=18&id=1407&mode=&type_pc2020=sametitleLevel-2

另外, 站務問題請到站務討論區裡發言, 這串是討論RS232傳接浮點數問題, 中間穿插一些站務上的問題, 看起來有點怪怪的…

作者 : witsh0928(doctor)
[ 貼文 26 | 人氣 2329 | 評價 30 | 評價/貼文 1.15 | 送出評價 2 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/25 下午 03:24:40

我很確定的傳輸是8bit

我試了
    float xp1,xp2;
    char buf[50];
    memset(buf, 0, sizeof(buf));
    snprintf(buf “%08.6f %08.6%”, xp1,xp2);

這個方式可以傳輸,但知道為什麼在PC端接收到的值
在偶數個都會lost掉…如下

     要傳輸的值 實際接收到的值
0.151618 0.121546 0.151618 0.121546
0.151213 0.181963
0.169578 0.112365 0.169578 0.112365
0.151233 0.131963
0.151318 0.161969 0.151318 0.161969
0.151213 0.181866

我該怎麼去解決比較好
     

作者 : kwong(kwong) 貼文超過200則
[ 貼文 257 | 人氣 739 | 評價 260 | 評價/貼文 1.01 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/25 下午 04:09:24

一般系統與系統互傳都是用ascii, 因為系統之間 float 的格式未必相同,
以前為了省傳輸量, 用 BCD.
eg. 123.456 會寫成 41 23 A4 56
41 的 4 是 bytes 數長度
A4 的 A 代表 小數點
如果是相同的系統, 直接用 float 便可以,
如果發現 float 轉換 ascii 時有誤差, 可以用 double.

作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2079 | 人氣 89850 | 評價 9940 | 評價/貼文 4.78 | 送出評價 78 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/25 下午 06:36:48

你想像中 浮點轉字串 問題, 其實並不存在, 因為, 你根本 完 全 沒 必 要 把 float 資料 轉換成 可讀 ASCII 文字.

一個 float 就是 4個 byte (即是 32 bit), 一次傳輸 8 bit 的話, 四次就能傳送一個 float. 把資料先轉換成可讀 ASCII 字串 是畫蛇添足之舉. 舉例說, 要把 a, b, c 三個 float 資料放到一個 char buffer,

float a = 1.1412f;
float b = 7.1465f;
float c = 4.1499f;

char buf[12];
memcpy( &buf[0], &a, sizeof(float) );
memcpy( &buf[4], &b, sizeof(float) );
memcpy( &buf[8], &c, sizeof(float) );

這樣就可以了.

要解讀的時候, 你只需要把資料複製上 float 資料的 memory 之上就可以了. 例如,

float x,y,z;
memcpy( &x, &buf[0], sizeof(float) );
memcpy( &y, &buf[4], sizeof(float) );
memcpy( &z, &buf[8], sizeof(float) );

而且, 所用到的 API 都只是 C library 的.

什麼 double, float, char, int, c string 在記憶體之內, 始終也是由某一個數目的 byte 去代表, 這樣想應該會讓你心理想好過點吧.

還有, double 的精確度 無疑是比 float 的精確度 高出很多. 但是, 當你強行把二進制的東西, 換成 10進制的字串, 你需要無限長的 10進制的字串 才能把資料準確的對換. 應用 double 之後, 就以為是準確, 是自欺欺人而已.

最後提提你, 不同的系統, byte ordering 可能會相反了, PC 的是 Small Endian. PC 以外的你要特別注意了.

作者 : kwong(kwong) 貼文超過200則
[ 貼文 257 | 人氣 739 | 評價 260 | 評價/貼文 1.01 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/25 下午 09:04:08

回覆白老鼠 : 在不同的系統上, float 的定義是不同的, 在 sun 上的 float 跟 intel 的 float 除了byte order 反轉外, 還是有點不同的, 即使表面看來一樣, 亦不能肯定, 如果輸出是到 mini 或 main flame, 許多時 parity 只能用 e-7-1 底 o-7-1, 更是只能用 ascii 去通過.

用 sprintf, 因為 float 的精度不足, 容易在轉換間出現精度誤差, 一般來說, 如果跟金錢有關的東西, 內部亦不會轉成 float 或 double 來處理, 而只以 ascii 來處理.

如果只是學生作業, 系統又全是 intel pc, 那便用不用轉來轉去了.

作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2079 | 人氣 89850 | 評價 9940 | 評價/貼文 4.78 | 送出評價 78 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/26 上午 01:31:39

回覆kwong : 我跟你的考慮可不同了, 當然, 普通的商用程式, 大概可以接納某情度的誤差, 但是, 對於 Signal Processing, 這個是不能夠接受的. 我相信不同系統的 float 定義也許會不同, 真的這麼的話, 只能作個別處理了, 除了多花 時間 和 精力, 並不存在技術上的不可能.

作者 : asingc(阿信 張)
[ 貼文 54 | 人氣 2189 | 評價 240 | 評價/貼文 4.44 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/26 上午 09:20:14

>回覆白老鼠 : 在不同的系統上, float 的定義是不同的, 在 sun 上的 float 跟 intel 的 float 除了byte order 反轉外, 還是有點不同的, 即使表面看來一樣, 亦不能肯定, 如果輸出是到 mini 或 main flame, 許多時 parity 只能用 e-7-1 底 o-7-1, 更是只能用 ascii 去通過.
>
>用 sprintf, 因為 float 的精度不足, 容易在轉換間出現精度誤差, 一般來說, 如果跟金錢有關的東西, 內部亦不會轉成 float 或 double 來處理, 而只以 ascii 來處理.
>
>如果只是學生作業, 系統又全是 intel pc, 那便用不用轉來轉去了.

剛找了一下, IEEE floating point spec
http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html
(大神找到 IEEE 自己的網頁, 但連進去之後被 access deny)

使用字串做數字運算, 聽起來很 COBOL. 使用 ASCII 表達10億需要 12 bytes, 這樣的值域, 可以用來存全世界所有的財富了吧. 這樣使用空間, 古早留下來的 COBOL 系統這樣設計還說得過去, 現在新的系統, 這樣做實在找不到合理的解釋.

Asing

作者 : kwong(kwong) 貼文超過200則
[ 貼文 257 | 人氣 739 | 評價 260 | 評價/貼文 1.01 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/4/26 上午 10:21:22

IEEE floating 確實是定義了 float, 以前用 borlandc 讀進了一個 invalid 的 float, 即時當了, 可是在 sun 上讀入(注意已經調好了byte order), 卻是一個數.

作者 : leona110(HB_AI)
[ 貼文 1 | 人氣 1 | 評價 0 | 評價/貼文 0 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/5/5 上午 09:42:19

我的書裡有提到型態轉換
但寫的不是很詳細我也不太會用
static_cast<>()
你可以早高手問問看如何使用

作者 : ma_hty(白老鼠(Gary))討論區板主 OpenGL卓越專家DirectX優秀好手C++頂尖高手貼文超過2000則人氣指數超過70000點
[ 貼文 2079 | 人氣 89850 | 評價 9940 | 評價/貼文 4.78 | 送出評價 78 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/5/5 下午 01:24:09

>IEEE floating 確實是定義了 float, 以前用 borlandc 讀進了一個 invalid 的 float, 即時當了, 可是在 sun 上讀入(注意已經調好了byte order), 卻是一個數.

( 純粹有點好奇… ) 一個 float 的 4 byte, 亂寫上去也不會讓程式當吧. 可否把情況細說一下?

作者 : kwong(kwong) 貼文超過200則
[ 貼文 257 | 人氣 739 | 評價 260 | 評價/貼文 1.01 | 送出評價 0 次 ] 
給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2005/5/5 下午 08:31:22

可能是 BORLAND C (V3.1) 的 BUG, 已經忘了該數值, (0xFE?? 0xFF??)
但在 SUN SPARC, SCO UNIX, VC 上都沒有此問題.

(PS: 以上只有 SUN SPARC 的 BYTE ORDER 是反轉的.)

未經允許不得轉載:GoMCU » [轉]浮點轉字串的寫法