PDA

نسخه کامل مشاهده نسخه کامل : ناقص بودن سوئیچ کیس؟



Life24
28-07-2013, 16:29
سلام
اخیرا متوجه شده ایم که مقدار Double در سوئیچ کیس کار نمی کند. و ماکروسافت هنوز فکری بابت این مشکل نکرده است.
کسی پیشنهادی دارد؟ و چرا این باگ را رفع نمی کند؟

Msba
28-07-2013, 18:34
چند مورد و نکته:
1-طرفداری نمی کنم.
2- یک عدد Double را می خواهید در چند شرط بررسی کنید؟ چند حالت دارد؟
3- در سوییچ کلا اعداد برای بررسی فقط بخش صحیح آن ها مد نظر است حال اگر عدد اعشاری باشد اعشار آن صرفه نظر می گردد یعنی مجبوریم cast اجباری انجام دهیم.
4-زمانی که سوییچ استفاده می شود شرط ها بهینه تر خواهند بود چرا که عمل بررسی ساده تر است. شرط ها پیاپی است.
5- تمامی پردازنده های رایانه Fixed Point هستند. این یعنی نمی توانند مستقیم روی اعداد اعشاری کار کنند. پس زمانی که می خواهند بررسی کنند، دو عدد صحیح را با هم مقایسه می کنند پس در نتیجه چون سوییچ هم برای بهینه سازی است پس ورودی آن نمی تواند یک متغیر اعشاری باشد.
پس این مورد یک باگ نیست. عموما بررسی شرط های Double در یک بازه خواهد بود در نتیجه استفاده از if در اینجا کارآمد تر است چرا که سوییچ بازه را بررسی نمی کند.

موفق باشید.

Life24
28-07-2013, 19:06
2- یک عدد Double را می خواهید در چند شرط بررسی کنید؟ چند حالت دارد؟

سلام.
فرض ورودی ما یک مقدار double است و در سوئیچ قرار میگیرد.و این سوئیچ مثلا 100 حالت دارد.حالا IF جالب هست؟!

_H2_
28-07-2013, 20:07
سلام

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

==============

هیچگاه یک متغییر اعشاری مانند double و float را یکراست و مستقیم با یک عدد مقایسه نکنید!
این میتواند یک اشتباه خاموش برنامه نویسی باشد.

متغییر های اعشاری همواره درصد بسیار بسیار کوچکی از تلرانس را همراه دارند.
شاید ظاهرشان با باطنشان متفاوت باشد!!!

مثال
در ماشین حساب ویندوز از عدد 4 جذر بگیرید (خوب پیچیده نیست میشود 2 !) و بعد این عدد را منهای 2 کنید، حدس میزنید جواب چند است؟؟؟
از نظر ریاضی صفر مطلق ولی از نظر اعداد اعشاری رایانه جواب ممکن است صفر نشود و بستگی به دقت پشتیبانی شده در عدد اعشاری دارد!


مجدد تاکید و تکرار میکنم، شما هیچگاه نباید یک عدد اعشاری را مستقیم با عدد دیگری مقایسه کنید و روی آن تصمیم بگیرید، چون میتواند نتایج متفاوتی داشته باشد.
بجایش اگر میتوانید از مقایسه == و =! احتراز کنید، و از ><>=<= استفاده کنید و اگر نمیتوانید باید فاصله متغییر از عدد مورد بررسی را معیار قرار دهید. (مثلاً با یک اپسیلون حداقلی در کارتان)


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

مثال عملی در #C ...
میدانیم که Sin زاویه 30 درجه یا همان PI/6 رادیان عدد 0.5 است
خوب چه انتظاری از کد زیر دارید؟؟؟

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر درست با معماری اعداد اعشاری رایانه آشنا نباشید، از جواب متعجب خواهید شد...

ولی کد صحیح این است.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
در این کد دقت یک میلیونیم را معیار قرار داده ایم و گفتیم تفاوت کمتر از یک میلیونیم در محاسبه ما مهم نیست و کد طبق انتظار کار خواهد کرد.


در نهایت در نظر داشته باشید که این مشکل Sin و Cos و... نیست که بگوید من استفاده نکردم پس خیالم راحت باشد...
این نکته خاموش در متغییرهای اعشاری میتواند هرجایی گریبانتان را بگیرد، شاید برنامه ای بنویسید و مدت ها هم بدون مشکل کار کند ولی شاید زمانی در یک تقسیم ساده دو عدد خاص خودش را نشان دهد و برنامه تان رفتار غیر منطقی از دید کاربر، انجام دهد...


این هم مشکل برنامه نویسی نیست و یکی از دو مورد جزئیاتی است که در سطح متغییرهای اعشاری در رایانه وجود دارد و برنامه نویسان همه زبان ها باید با آن آشنا باشند و ان را در کدشان لحاظ کنند.
(مورد دوم اعداد اعشاری هم تفاوت محاسبات باینری اعشاری و مبنای ده اعشاری است که خودش مبحث طولانی دیگری است...)


فرض ورودی ما یک مقدار double است و در سوئیچ قرار میگیرد.و این سوئیچ مثلا 100 حالت دارد.حالا IF جالب هست؟!
در شرایط خاص و با کمی دقت، احتمالاً میتوانید همچین حالت های وحشتناکی را (!:n02:!) با کمک راه حلهای جایگزینی مانند آرایه ها به زیبایی بیشتر انجام دهید.

موفق باشید.

szh_1367
28-07-2013, 21:31
سلام

به مطلب بسیار مهمی اشاره کردید! حیفم امد، اجازه دهید جمله تان باز و شرح و تفسیرش کنم...

==============

هیچگاه یک متغییر اعشاری مانند double و float را یکراست و مستقیم با یک عدد مقایسه نکنید!
این میتواند یک اشتباه خاموش برنامه نویسی باشد.

متغییر های اعشاری همواره درصد بسیار بسیار کوچکی از تلرانس را همراه دارند.
شاید ظاهرشان با باطنشان متفاوت باشد!!!

مثال
در ماشین حساب ویندوز از عدد 4 جذر بگیرید (خوب پیچیده نیست میشود 2 !) و بعد این عدد را منهای 2 کنید، حدس میزنید جواب چند است؟؟؟
از نظر ریاضی صفر مطلق ولی از نظر اعداد اعشاری رایانه جواب ممکن است صفر نشود و بستگی به دقت پشتیبانی شده در عدد اعشاری دارد!


مجدد تاکید و تکرار میکنم، شما هیچگاه نباید یک عدد اعشاری را مستقیم با عدد دیگری مقایسه کنید و روی آن تصمیم بگیرید، چون میتواند نتایج متفاوتی داشته باشد.
بجایش اگر میتوانید از مقایسه == و =! احتراز کنید، و از ><>=<= استفاده کنید و اگر نمیتوانید باید فاصله متغییر از عدد مورد بررسی را معیار قرار دهید. (مثلاً با یک اپسیلون حداقلی در کارتان)


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

مثال عملی در #C ...
میدانیم که Sin زاویه 30 درجه یا همان PI/6 رادیان عدد 0.5 است
خوب چه انتظاری از کد زیر دارید؟؟؟

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر درست با معماری اعداد اعشاری رایانه آشنا نباشید، از جواب متعجب خواهید شد...

ولی کد صحیح این است.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
در این کد دقت یک میلیونیم را معیار قرار داده ایم و گفتیم تفاوت کمتر از یک میلیونیم در محاسبه ما مهم نیست و کد طبق انتظار کار خواهد کرد.


در نهایت در نظر داشته باشید که این مشکل Sin و Cos و... نیست که بگوید من استفاده نکردم پس خیالم راحت باشد...
این نکته خاموش در متغییرهای اعشاری میتواند هرجایی گریبانتان را بگیرد، شاید برنامه ای بنویسید و مدت ها هم بدون مشکل کار کند ولی شاید زمانی در یک تقسیم ساده دو عدد خاص خودش را نشان دهد و برنامه تان رفتار غیر منطقی از دید کاربر، انجام دهد...


این هم مشکل برنامه نویسی نیست و یکی از دو مورد جزئیاتی است که در سطح متغییرهای اعشاری در رایانه وجود دارد و برنامه نویسان همه زبان ها باید با آن آشنا باشند و ان را در کدشان لحاظ کنند.
(مورد دوم اعداد اعشاری هم تفاوت محاسبات باینری اعشاری و مبنای ده اعشاری است که خودش مبحث طولانی دیگری است...)


در شرایط خاص و با کمی دقت، احتمالاً میتوانید همچین حالت های وحشتناکی را (!:n02:!) با کمک راه حلهای جایگزینی مانند آرایه ها به زیبایی بیشتر انجام دهید.

موفق باشید.



نکته بسیار بسیار مهمی هست این رو افرادی مثل من متوجه میشوند که برنامه بدون خطا اجرا میشود اما گاهی ( به ندرت ) نیز جواب درست نیست ولی متوجه نمیشوید این اشتباه از کجاست مدتها به دنبال اشکال میگردید هربار کلافه تر از مرتبه قبل :n13::weird::grrr: - حتی کار به جایی رسید که بعضی از کلاس های مهم رو بازنویسی کردم هرچند که بدون مشکل اجرا میشدند

مدت ها طول کشید تا یک مقایسه ساده اما بسیار بسیار مهم اعشاری که باعث مشکل میشد را پیدا کردم

iranch
29-07-2013, 00:23
4-زمانی که سوییچ استفاده می شود شرط ها بهینه تر خواهند بود چرا که عمل بررسی ساده تر است. شرط ها پیاپی است.
درود بازه از نظر ریاضی رو میدانم چیه.مثلا میگیم فلان عدد در بازه فلان مجموعه است. اینجا منظور از بازه دقیقاه چیه؟ :n16: (ریاضی افتضاح!!==0)

Msba
29-07-2013, 18:16
اینجا هم منظور همان است.به توضیحات جناب H2 دقت کنید. به طور مثال اینگونه اعداد فی مابین مقایشه شوند.
مثلا به جای اینکه بگوییم برابر است با x بگوییم اگر کوچکتر مساوی با x بود. یا بالعکس. یا اگر بین x و y بود. یا عدد را گرد کنیم و.....
اینگونه خطای محاسبات تاثیری روی شرط ندارد.

موفق باشید.

_H2_
29-07-2013, 20:03
سلام

اینجا منظور از بازه دقیقاه چیه؟
دوستمان Msba توضیح دادند و برای آنکه شهودی و بهتر متوجه شوید مثالی میزنم...

این دستور بررسی در یک نقطه خاص است
d == 5

ولی این دستور بررسی در یک بازه است
d >= 4 && d <= 6

این بازه میتواند خیلی کوچک باشد
d >= 4.999999 && d <= 5.000001
که دستور فوق با دستور زیر برابر است
Abs(d - 5) <= 0.000001

البته بازه میتواند از یک سمت تا بینهایت امتداد داشته باشد
d > 61.8

بازه ریاضی یعنی یک محدوده پیوسته، یک range پیوسته از یک نقطه شروع تا یک نقطه پایان (حالا این نقطه میتواند بینهایت هم باشد)