欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7302|回復: 23
收起左側

納悶,51單片機無法計算乘積為上萬的乘法?

  [復制鏈接]
ID:71233 發表于 2019-8-29 11:34 | 顯示全部樓層 |閱讀模式
本帖最后由 新新科技 于 2019-8-29 12:01 編輯

這幾天在設計一段程序時,需要計算相乘積為上萬甚至上十萬的乘法運算,大致是這樣的:
      unsigned int tt;//使用STC單片機
      tt=(shuiliang*(100-temp)*0.01;//
其中,shuiliang值為800至1500,temp值為0至100。
通過多次的試驗,明明shuiliang(指定1500)和temp(指定30)的代入數值不會出錯,但tt的計算結果總是出錯(用Proteus_7.5仿真或實物均如此),真的很納悶,后來通過分析,難道51單片機真的無法計算乘積為上萬的乘法?最終確定改變運算順序(先除,讓乘積不再太大),具體如下:
      tt=(shuiliang/100)*(100-temp);
這樣的運算順序,計算結果才是正確的。
請教各位大師,51單片機在做乘法計算的,最大只能完成乘積為多少的乘法運算?

回復

使用道具 舉報

ID:149144 發表于 2019-8-29 15:57 | 顯示全部樓層
unsigned int tt ; 最大值是多少 ?   65535 ??
1500 * 70 = 105000  
回復

使用道具 舉報

ID:401564 發表于 2019-8-29 16:12 | 顯示全部樓層
理論上來說,8051可以計算無限大運算,所有運算,包括微積分之類的高數
而實際上,8051的能力只能說是可以無限接近無限,總的來說的,10億以內的運算是絕對可以的。
對于C的計算來說,它取決于KEIL這個軟件的編譯器,不同類型的數據類型就會有不同的長度,運算結果超過這個長度的,就會不要了
而在C中,不同數據類型進行運算時,會先強制轉換成同一個類型再進行運算,而你這個就是這種情況
你想要運算結果正確,所有的數據類型得是:雙精度浮點數,好像KEIL中這個類型應該是有16位的,如果長度是16位的,那么:在65536以下的運算就是正確的,超過這個值的就只取16位的結果,如果是32位長度,那就更精確了
回復

使用道具 舉報

ID:149389 發表于 2019-8-29 16:29 | 顯示全部樓層
本帖最后由 weidoit 于 2019-8-29 16:46 編輯


1500*(100-30)=105000  (存不下了),試試長整型。
回復

使用道具 舉報

ID:71233 發表于 2019-8-29 17:27 | 顯示全部樓層
1500*100=150000,乘積超過65536,那是一定的,只不過這個結果不是最終的結果,因為后面還要除以100,具體見上面的計算式子。問題出在KEIL,那是極有可能的,因為我用的版本是7.5版的。
回復

使用道具 舉報

ID:401564 發表于 2019-8-30 00:44 | 顯示全部樓層
這跟后面除以100沒有關系的,超過16位的數字,就只取16位的數據,多出來的就不要了
你可以使用long型數據,,32位,足夠你用的了
回復

使用道具 舉報

ID:511890 發表于 2019-8-30 01:09 | 顯示全部樓層
不是單片機的問題,是C語言變量類型字節長度的問題。U int 最大值65535。把tt的類型unsigned int改為long就行
回復

使用道具 舉報

ID:65956 發表于 2019-8-30 08:35 | 顯示全部樓層
unsigned int tt;把這個改為unsigned long tt;就OK了,這個最大可以達到4294967295,這是最大值
回復

使用道具 舉報

ID:208271 發表于 2019-8-30 08:58 | 顯示全部樓層
8051單片機是8位單片機,數據儲存器是16位的,最大的數據是65536,超過這個數據單片機儲存就有問題,但對于程序來說,就是定義問題,定義int就65536,超過了就會溢出,采用LONG或者FLOAT型,這是編譯器的問題。還是要了解一下編譯器的C語言用法。
回復

使用道具 舉報

ID:208271 發表于 2019-8-30 09:02 | 顯示全部樓層
unsigned int tt;//使用STC單片機tt=(shuiliang*(100-temp)*0.01;/
這個tt是int類型,不能*0.01,可以/100,數據類型不對一樣出錯的,編譯器不會自動轉換識別數據類型的,把tt改為float可以用*0.01,不會出錯。
樓主還是要了解清楚C的數據類型啊!
回復

使用道具 舉報

ID:605370 發表于 2019-8-30 09:34 | 顯示全部樓層
建議你更換數據類型,int長度不夠,試試long
回復

使用道具 舉報

ID:71233 發表于 2019-8-30 18:12 | 顯示全部樓層
改為
    unsigned long tt;
    tt=(shuiliang*(100-temp)/100;
照常不行!
回復

使用道具 舉報

ID:71233 發表于 2019-8-30 18:22 | 顯示全部樓層
無論把tt改為什么類型都不行,我總是覺得要么是編譯器的限制,要么就是51單片機的只能分配2個字節的寄存器來存儲運算過程中的中間數,我檢驗了,的確在計算乘法的時候,超過兩個八位字節的,只截取了后面兩個字節的數值,如1500*100=150000=0x249F0,結果只有0x49F0繼續參加后面的計算。
回復

使用道具 舉報

ID:401564 發表于 2019-8-30 23:08 | 顯示全部樓層
我的天呀!為什么會這這種想法呢,根本是你自己的方法不對
所有的變量都統一的改成long型,所有的!
temp不是變量嗎?shuiliang是不是呢?
那么多人幫你回答了那么多
你是怎么驗證的呢?
還是我前面的回答:10億以內的運算是可以的,難道你沒有見過或者聽說過基于8051的計算器嗎
回復

使用道具 舉報

ID:370639 發表于 2019-8-31 08:24 | 顯示全部樓層
數據類型不對吧
回復

使用道具 舉報

16#
無效樓層,該帖已經被刪除
17#
無效樓層,該帖已經被刪除
ID:149642 發表于 2020-6-11 22:31 | 顯示全部樓層
匯編都可以算到億億以上,只要你的寄存器夠多,
ABCDEF*ABCDEF=(AB*100*100+CD*FF+EF)*(AB*100*100+CD*FF+EF)
回復

使用道具 舉報

ID:491577 發表于 2020-6-14 18:36 | 顯示全部樓層
樓主不明白單片機計算中每一步都不能夠有數據溢出,否則出錯,不是最后一步不溢出就行。用強制轉換就可以了。比如: tt=(shuiliang*(100-temp)/100;改成: tt=((long)shuiliang*(100-temp)/100;
回復

使用道具 舉報

ID:877285 發表于 2021-2-1 09:38 | 顯示全部樓層
解決問題沒,我和你的問題一樣
回復

使用道具 舉報

ID:712493 發表于 2021-2-1 14:21 | 顯示全部樓層
hhh402 發表于 2020-6-14 18:36
樓主不明白單片機計算中每一步都不能夠有數據溢出,否則出錯,不是最后一步不溢出就行。用強制轉換就可以了 ...

看看 這個對頭  還是數據類型的問題 不行就一步一步寫嘛
回復

使用道具 舉報

ID:882150 發表于 2021-2-1 19:26 | 顯示全部樓層
數據類型有問題 建議用long
回復

使用道具 舉報

ID:877285 發表于 2021-2-2 09:01 | 顯示全部樓層
實例1:  gPWM.Duty 輸出值為異常值
         Test_A = (long)4580;
          
          Test = (long)Test_A*(long)100;
          
          gPWM.Duty = Test / (gPWM.High_Cnt + gPWM.Low_Cnt);

實例2:  gPWM.Duty 輸出值為正常值   
          
          Test = (long)4580*(long)100;
          
          gPWM.Duty = Test / (gPWM.High_Cnt + gPWM.Low_Cnt);

誰能解釋為啥?
回復

使用道具 舉報

ID:879809 發表于 2021-2-2 18:10 | 顯示全部樓層
die123123 發表于 2021-2-2 09:01
實例1:  gPWM.Duty 輸出值為異常值
         Test_A = (long)4580;
          

類似 (long)4580的寫法改成4580l。
回復

使用道具 舉報

ID:158467 發表于 2021-7-6 09:39 | 顯示全部樓層
Y_G_G 發表于 2019-8-30 23:08
我的天呀!為什么會這這種想法呢,根本是你自己的方法不對
所有的變量都統一的改成long型,所有的!
temp不是 ...

統一換成長整型也有問題,這個跟編譯器的IDE是否能自動識別 類型和準確隱式轉換有關,存在常量100就會默認為表達式為16位的運算,解決方法1是如樓主的:前面先除以100,控制數據在16位數據內,這樣是可以的。另一種方法是:先定義位unsiged long  tt;   tt=((unsiged long)shuiliang/(unsiged long)100)*((unsiged long)100-(unsiged long)temp))
回復

使用道具 舉報

ID:158467 發表于 2021-7-6 09:39 | 顯示全部樓層
統一換成長整型也有問題,這個跟編譯器的IDE是否能自動識別 類型和準確隱式轉換有關,存在常量100就會默認為表達式為16位的運算,解決方法1是如樓主的:前面先除以100,控制數據在16位數據內,這樣是可以的。另一種方法是:先定義位unsiged long  tt;   tt=((unsiged long)shuiliang/(unsiged long)100)*((unsiged long)100-(unsiged long)temp))
回復

使用道具 舉報

27#
無效樓層,該帖已經被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表