有這么一個
計算公式:
PHA_adj=65536-18919*(T_Pimp-time_cnt)/time_cnt;
其中:
PHA_adj:unsignedint
T_Pimp:常數,等于3266
time_cnt:unsignedint范圍在2000至3000之間
這個公式有錯嗎,如果錯了錯在哪?怎么改才能算出期望值?
(KEILC518位機等同于8052)PHA_adj結果精度需保證在0.1%內
呵呵答案在后面給出.
網友評論:分開之后發覺,那個INT×INT后,INT是放不下結果的。
網友評論:直接開長整型數據定義
網友評論:PHA_adj=~((unsignedlong)18919*(T_Pimp-time_cnt)/time_cnt)+1;
不如:
PHA_adj=65536-(unsignedlong)18919*(T_Pimp-time_cnt)/time_cnt;好
為什么呢,什么原因呢
網友評論:很煩強制轉換,那玩意很多時候是個隱性炸彈。。。
直接開長整型數據定義
答:直接開長整型定義會帶來如下后果:
占用數據存儲器多,代碼長,執行時間長.
28樓:樓主所說的好是什么方面的??
25樓:
PHA_adj=~((unsignedlong)18919*(T_Pimp-time_cnt)/time_cnt)+1;
不如:
PHA_adj=65536-(unsignedlong)18919*(T_Pimp-time_cnt)/time_cnt;好
為什么呢,什么原因呢
答:PHA_adj=65536-(unsignedlong)18919*(T_Pimp-time_cnt)/time_cnt;代碼比較少一點.
網友評論:答樓上兩位
27樓:很煩強制轉換,那玩意很多時候是個隱性炸彈。。。
直接開長整型數據定義
答:直接開長整型定義會帶來如下后果:
占用數據存儲器多,代碼長,執行時間長.
-------------------------------------------------------------
且,你以為你沒開長整型,代碼就短了?執行時間就短了?至于占用RAM多的問題,你開成局部變量就是了,用完自動被編譯器釋放了。
網友評論:且。。。
xuehongren發表于2008-10-2410:43侃單片機←返回版面
29樓:答樓上兩位
27樓:很煩強制轉換,那玩意很多時候是個隱性炸彈。。。
直接開長整型數據定義
答:直接開長整型定義會帶來如下后果:
占用數據存儲器多,代碼長,執行時間長.
-------------------------------------------------------------
且,你以為你沒開長整型,代碼就短了?執行時間就短了?至于占用RAM多的問題,你開成局部變量就是了,用完自動被編譯器釋放了。
沒必要得整成長整型吧,照你這么說,那只要牽扯到LONGINT的都定義成LONGINT?
至于你說的隱性炸彈應該是可以避免的
網友評論:(unsignedlong)18919=18919L
65536-x=取補碼(~x)+1,且不牽涉進位。
17L前面的65536沒加L或(unsignedlong)
剛才試了下,(unsignedlong)18919寫成18919L確實沒問題,但不知道其它是否也有如此簡寫:
如:,(unsignedint)189等
網友評論:一個A人的說法~~~
網友評論:有哪位能給鄙人推薦一本好的C51方面的書啊
網友評論:所長的程序對,但是精度降低了。
網友評論:我記得我也做過這樣的事情,不過沒關心什么,用double就行了,當然程序是長了點,資源也占多點,但我精度有了保證。
網友評論:同意擴展數據類型的長度
我記得我也做過這樣的事情,不過沒關心什么,用double就行了,當然程序是長了點,資源也占多點,但我精度有了保證。
對數據類型的定義應該還是滿足要求就行,如這個問題,產品需要的精度為小于等于0.1%,所以就只需轉成LONGINT就行了,計算也不會產生溢出錯誤
網友評論:我在程序內從未用過小數,為我覺得一切小數在單片機里都是以二進制整數來實現的,不知各位的理解。
網友評論:65536L-18919L*(T_Pimp-time_cnt)/time_cnt
=65536-18919L*(T_Pimp-time_cnt)/time_cnt
網友評論:大家就頂頂吧
網友評論:頂一下吧
網友評論:因為C51的編譯器默然的整型為16位,所以對于小于32768的數就會認為是整型,做16位的運算,
對于運算結果超出16位的,就被截斷了。如果運算結果最高位為1的,還要進行符號擴展,例如
如果你寫的是j=20000*2;,結果就是0xFFFF9C40了。對于大于等于32768的數,就會先自動擴展為
longint型,然后再運算,這時結果就不會出錯了,為了安全起見,不管它多大,還是明確指定為好:
j=20000L*4;
j=20000L*2;
j=65535L*4;
如果你換成keilCARM,就不會存在這個問題了,因為ARM是32位的,int就是32位的。
網友評論:你的解釋我再驗證下,不過先感謝你了.
網友評論:保留整數,省掉小數.
網友評論:飄過
網友評論:8位的類似89C52
網友評論:應該是溢出。
網友評論:PHA_adj=84455-(unsignedlong)18918*T_Pimg/time_cnt;
網友評論:要建立“數值與類型相互獨立”的概念
常數是有類型的,某些數值有默認類型,那只能當作特例
數學等價變換:
65536-18919*(T_Pimp-time_cnt)/time_cnt
=65536-(18919*(T_Pimp/time_cnt-1))
=65536-(18919*(T_Pimp/time_cnt)-18919)
=84455-18919*(T_Pimp/time_cnt)
C語言表達式:
84455uL-(18919uL*T_Pimp)/time_cnt
網友評論:PHA_adj=65536-(unsignedlong)(18919*(T_Pimp-time_cnt))/(unsignedlong)time_cnt;
網友評論:PHA_adj=65536-((unsignedlong)18919*(T_Pimp-time_cnt))/(unsignedlong)time_cnt;
對有的編譯器,17樓的能過。
網友評論:應該是對所有編譯器17樓都能過吧
網友評論:對于32位變量和16位變量的運算,如果不強制類型轉換有的向16位看齊,有的向32位看齊,我的印象是IARforMSP430向16位看齊,而IARforARM卻向32位看齊,是不是對于片內RAM資源少的傾向節省RAM,而對片內RAM資源多的傾向浪費RAM,也許是由IAR的配置確定。16位變量和8位變量的運算也是這樣
網友評論:我只看到了譚浩強老師書上說的,不同數據類型之間的混合運算,都是短字節數向長字節數對齊.
網友評論:譚浩強老師書上說的曾讓我困惑了很久,這個世界沒有絕對的權威。
網友評論:是的他的書有些寫得也不全面,不過他的書還是寫得很好的.
網友評論:aa
網友評論:qqqqqqqqqqqqqq
網友評論:unsignedlongsum;
sum=T_Pimp-time_cnt;
sum=18919*sum;
sum=sum/time_cnt;
PHA_adj=65536-(unsignedint)sum;
網友評論:樓上的方法也可以啰不過這樣寫有點麻煩.
網友評論:PHA_adj=(unsignedint)(65536-18919.0*(T_Pimp-time_cnt)/(1.0*time_cnt));
先做成浮點數,再轉換為int
網友評論:樓上的你的結果沒錯,但不是最好的處理辦法.
網友評論:18919.0的出現,乘法就變成了浮點數乘法,代碼增加不少.
網友評論:如果實在32系統里,這個公式是不會溢出的,但如果在int為16位的系統里,這個公式確實會溢出。還有你也沒有說清楚要求的精度要求,當精度要求比較高時,該公式必須轉換成浮點類型進行計算
網友評論:在KEIL的C51編譯unsignedint最大0XFFFF
18919*(T_Pimp-time_cnt)一定溢出了,
但ARM中unsignedint最大0XFFFFFFFF,結果沒問題
網友評論:我的是8位的MCU呢相當于80C52.
網友評論:不過,樓主的問題有點小兒科了。
類似程序編譯驗證一下,馬上可以得出結果正確與否。
這問題拿不出臺面的,不用分享了。
網友評論:我問了下用C做了幾年產品的同事,他居然還找不到BUG,呵呵,我的目的是讓新手增加點經驗.
網友評論:如果換編譯器,這些數學計算還是要重新確認一次.
另外,還是要注意邊界測算.我的方法也是數據擴展,但絕對不轉浮點。
網友評論:畢業后二十年了,總算接了個大工程,造一根三十米煙囪,工期兩個月,造價三十萬,不過要墊資。總算在上個月底搞完了。今天人家去驗收,被人罵得要死,還沒有錢拿。媽的!圖紙看反了,人家是要挖一口井!
網友評論:還是把整型寫明白好,2字節的就定義成短整型,4字節的就定義成長整型,勉得各個系統不一樣.
網友評論:如果不是就事論事,光一個式子,哪有錯對可論的。
所謂錯者,指那個結果與期望的不一致。樓主得先給一個樣品值與使用環境,才能評論錯那里了。
網友評論:答案前面已經有人說了啊