اطلاعیه

Collapse
No announcement yet.

میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

    سلام دوستان، صبح بخیر....

    من یه رشته هشت کاراکتری که نشون دهنده یه عدد در مبنای هگز هست رو می خوام به یه عدد در مبنای دسیمال تبدیل کنم.... برنامه ای نوشتم که با گرفتن یک به یک این کاراکترها این تبدیل رو انجام میده... اما یه اتفاق جالب این وسط میفته... و اون هم اینه که اگر عدد بزرگ باشه... خطا وجود داره. نوع متغیری رو که قراره عدد دسیمال در اون قرار بگیره یه بار unsigned long int در نظر گرفتم وقتی دیدم خطا داره... دفعه بعد float در نظر گرفتم ولی همچنان این خطا باقی است. من برای نشون دادن عدد دسیمال نهایی روی LCD از دستور ltoa یا ftoa استفاده کردم.

    رشته هایی رو که برای تست در نظر گرفتم، اینها هستند(مقادیر معادل دسیمال رو هم روبروی هر رشته نوشتم):
    E0000000=3758096384
    0E000000=234881024
    00E00000=14680064
    000E0000=917504
    0000E000=57344
    00000E00=3504
    000000E0=224
    0000000E=14

    اما جواب هایی که برای unsigned long int می گیرم:
    برای اولین حالت یه عدد منفی
    دومین: 234881056 می بینید خطا داره! بقیه موارد دقیق بدست می آیند!

    و جوابهایی که برای حالت float می گیرم:
    حالت اول: 3758096896
    دومین: 234881056
    سومین: 14680066
    چهارمین: 917507.125
    پنجمین: 57344.007812
    ششمین: 3584
    هفتمین: 244.000030
    هشتمین: 14

    شما می دونید چرا اینطور میشه؟

    بی نهایت سپاس از همفکری شما :biggrin:


    همیشه بزرگوار تر از آن باشید که برنجید
    و نجیب تر از آن باشید که برنجانید!

    #2
    پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا دا

    سلام با توجه به مقادیر float
    یک الگویی داره تکرار میشه:
    حالت اول:
    E0000200
    دوم:
    E000020
    سوم:
    E00002
    برای اونای دیگه تبدیل نکردم اما همین الگو رو این سه تا میتونه بعضی چیز ها رو نشون بده برای دومین unsigned long int هم دقیقا همین وضعه که دقیقا مثل float هست
    علت رو نمیدونم ولی اگه از نحوه ارسال دیتا مطمئن هستید و میتونید از کد زیر استفاده کنید:
    حقیقتش نمیدونم مشکل چیه و برام هم مهم نیست! چون در اینجور مواقع من خودم تابع رو مینویسم برای اینکه دقیق میدونم چی لازم دارم و پارامترها مشخصه دیگه لازم نیست برم یه تابع آماده پیدا کنم و بشینم بخونم چی گفته مگه اینکه نتونم اون تابع رو خودم بنویسم یا نصرفه.
    با فرض داشتن کارکتر نول و بزرگ بودن حروف برای اعداد بزرگتر از ۹ تابع tabdil زیر برای کار شماست:
    کد رو تو کامپیوتر نوشتم ولی قاعدتا اون تابع باید رو میکرو جواب بده

    کد:
    #include<iostream>
    using namespace std;
    char s[]="000126A0\0";
    unsigned long int tabdil(char* a){
    	unsigned long int b=0;
    	while(*a != '\0'){
    		if (*a < 65){
    			b*=16; // Base is 16. Digit shifting.
    			b+= ((unsigned long int) *a) - 48; // '0' = 48 --> Value of char variable.
    		}
    		else {
    			b*=16; // Base is 16. Digit shifting.
    			b+= ((unsigned long int) *a) - 55; // 'A' = 65 But A = 10 in hexadecimal --> 65 - 10 = 55
    		}
    	a++;
    	}
    	return b;
    }
    int main(){
    	unsigned long int x;
    	x=tabdil(&s[0]);
    	cout<<x<<'\n';
    	return 0;
    }

    ممکنه مبهم به نظر برسه کد میدونم
    اگه جاییش واضح نبود بفرمایید تا بیشتر توضیح بدم
    با تشکر

    دیدگاه


      #3
      پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

      سلام ممنون دوست عزیز

      من هم دقیقا یه تابع مشابه تابع شما نوشتم و بر همین اساس تبدیل رو انجام دادم... نکته جالب اینجاست که برای اعداد کوچک مشکلی پیش نمی یاد و این خطا برای اعداد بزرگتر رخ میده!
      من برای اینکه بتونم عدد دسیمال بدست اومده رو روی lcd به صورت یک رشته نشون بدم از دستور ltoa استفاده کردم. ممکنه این خطا توسط این دستور ایجاد شده باشه؟

      قدر دان راهنمایی های شما خواهم بود... :biggrin:
      همیشه بزرگوار تر از آن باشید که برنجید
      و نجیب تر از آن باشید که برنجانید!

      دیدگاه


        #4
        پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

        ---
        اگر روزی بفهمی همه چیزایی که از بچگی تا حالا بهت گفتن بی اساس یا دروغه چه حالی میشی؟
        کارمندان نابکار، از دزدان و آشوبگران بیشتر به کشور آسیب ميآ‌رسانند

        دیدگاه


          #5
          پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

          سلام ممنون دوست عزیز اینم کد برنامه... چون برنامه تست بوده توی main نوشتم...
          کد:
          unsigned long int ID;
               char card[9], c[9];
               for (i=0;i<8;i++){ 
                 for (k=0;k<8;k++) card [k]='0';
                 card[i]='E';
                 ID=0;
                 for (j=0;j<8;j++){ 
                     switch (card[j]){ 
                       case 'A':
                       case 'B':
                       case 'C':         
                       case 'D':
                       case 'E':
                       case 'F': 
                       ID=ID+((card[j]-55)*pow(16,(7-j)));
                       break;
                           
                       default:
                           ID=ID+((card[j]-48)*pow(16,(7-j))); 
                           break;      
                       };
                     }; 
                 lcd_gotoxy(0,1);
                 ltoa(ID,c);  
                 lcd_puts(c);
                 delay_ms(5000); 
                   };
          همیشه بزرگوار تر از آن باشید که برنجید
          و نجیب تر از آن باشید که برنجانید!

          دیدگاه


            #6
            پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

            ---
            اگر روزی بفهمی همه چیزایی که از بچگی تا حالا بهت گفتن بی اساس یا دروغه چه حالی میشی؟
            کارمندان نابکار، از دزدان و آشوبگران بیشتر به کشور آسیب ميآ‌رسانند

            دیدگاه


              #7
              پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

              خیلی ممنون از راهنمایی اتون....
              به جای فانکشن pow قبلا نوشته بودم:
              16^(7-j)

              و مشکل همچنان باقی بود، یه بار هم به جای ltoa از دستور sprintf استفاده کردم و توی منوی پروجکت تنظیمات مربوط به قبول داده از نوع long رو هم تنظیم کردم ولی مشکل همچنان باقی بود...

              با اینحال در اولین فرصت چک می کنم و نتیجه رو به اطلاعتون می رسونم...
              همیشه بزرگوار تر از آن باشید که برنجید
              و نجیب تر از آن باشید که برنجانید!

              دیدگاه


                #8
                پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

                آرایه c رو که 9 خونه تعریف کردید افزایشش بدید. بنابر تجربه خودم وقتی در نشون دادن رقم ها، به مشکل برمیخورم یه جایی مقدار حافظه ای که تعریف شده کم بوده.
                بهتره از دستور sprintf استفاده کنی. به نظرم دردسرش کمتره :smile:
                ... و (بدانيد) گرفتن تصميمهاى محكم (براى رسيدن به اهداف بزرگ) با خوش گذرانى و سفرهآ‌هاى رنگين سازگار نيست و چه بسيار كه خواب شبانه تصميمهاى محكم روز را از ميان برده و تاريكيآ‌ها، خاطره همتآ‌هاى بلند را از يادها محو كرده است. (نهجآ‌البلاغه، خطبه211)

                امام علي (ع):کسي که به وقت ياري رهبرش در خواب باشد، با لگد دشمنش بيدار مي شود (غررالحکم،ص 422)

                دیدگاه


                  #9
                  پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

                  مجدد برنامه رو تست کردم.... دقیقا مشکل از فانکشن pow از توابع کتابخانه ای math بود... جالبه اصلا فکر نمی کردم که توابع این کتابخانه مشکلی داشته باشه...

                  توابع ftoa و ltoa کارشون درسته، ولی تابع sprintf با وجود اینکه از منوی project تنظیم می کنم که long رو هم قبول کنه برای اعداد بزرگ صفر برمی گردونه.

                  ممنون از همفکری همه دوستان
                  همیشه بزرگوار تر از آن باشید که برنجید
                  و نجیب تر از آن باشید که برنجانید!

                  دیدگاه


                    #10
                    پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

                    با سلام،

                    زمانی که از Sprintf برای long استفاده میکنید، علاوه بر ست کردن کامپایلر برای long باید در خود Sprintf هم از L استفاده کنید. مثلا "Addr: %08lX" ، این کار رو هم کردید؟

                    به این هم یه نگاهی بندازید، بد نیست، ایده میده، یه چیز تو مایه های Sprintf منتها کم حجم تر و سریعتر :

                    http://s5.picofile.com/file/8123952892/Monitor.rar.html
                    مادامی که از شخصی یاد میشود، او و افکارش زنده اند ....

                    Sh_Nourbakhsh@Yahoo.com

                    http://s2.picofile.com/file/7170362468/_Wall_e_.jp

                    دیدگاه


                      #11
                      پاسخ : پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

                      نوشته اصلی توسط Nourbakhsh Rad
                      با سلام،

                      زمانی که از Sprintf برای long استفاده میکنید، علاوه بر ست کردن کامپایلر برای long باید در خود Sprintf هم از L استفاده کنید. مثلا "Addr: %08lX" ، این کار رو هم کردید؟

                      به این هم یه نگاهی بندازید، بد نیست، ایده میده، یه چیز تو مایه های Sprintf منتها کم حجم تر و سریعتر :

                      http://s5.picofile.com/file/8123952892/Monitor.rar.html
                      راستش رو بخواین، نه! :redface: الان تست کردم، دیدم که sprintf هم طبق فرمایش شما مشکل نداره...
                      پس تنها مشکل فقط تابع pow بود.... :biggrin:

                      با سپاس فراوان
                      همیشه بزرگوار تر از آن باشید که برنجید
                      و نجیب تر از آن باشید که برنجانید!

                      دیدگاه


                        #12
                        پاسخ : میکرو برای نشون دادن اعداد بزرگ خطا داره!! دلیلش چی میتونه باشه؟

                        بعید میبینم pow هم مشکل خاصی داشته باشه ....

                        کدی هم که نوشتید، هم کنده و هم اینکه اصولی نیست، یه نگاهی به روتین xatoi در فایل monitor.c بندازید، برای تمام پایه ها و به بهترین شکل ممکن این کار رو انجام داده، البته اگر خواستید استفاده کنید، باید کمی دستکاری و کامل بشه، ضمن اینکه از pow هم استفاده نکرده ....
                        مادامی که از شخصی یاد میشود، او و افکارش زنده اند ....

                        Sh_Nourbakhsh@Yahoo.com

                        http://s2.picofile.com/file/7170362468/_Wall_e_.jp

                        دیدگاه

                        لطفا صبر کنید...
                        X