Bonus score / C# versus JS issue / Head scratcher
Линк към задачата в Judge: Bonus Score
Следното решение с JS дава 100% верни отговори в Judge: http://pastebin.com/Ta5kpPTy
Аналогично решение със C# дава само 70% верни отговори: http://pastebin.com/FsQ1zT75
Проблемът е в това, че C# изчислява различно следните редове от JS:
bonusPoints = n * 20 / 100; и
bonusPoints = n * 10 / 100;
Ако заменя 20/100 и 10/100 съответно с 0.2 и 0.1, също получавам 100% в Judge със C#.
Защо при n = 2703, както в примерът на задачата, bonusPoints са 270 при 10%, а не 270.3?
За мен 10/100 е равно на 1/10 и на 0.1, но тук имаме различен резултат.
Не е достатъчно. Един израз има тип, който се определя от типовете на променливите, които участват в него.
Изразът int * int / int е същото като int * (int / int) или каквато и да е комбинация със скоби - след като участват само интове изразът също е инт.
Достатъчно е в случая кое да е от числата да е double, стига при първата операция int * int да не се получи препълване. Т.е. вярно ще работи така:
(double)n * 10 / 100, n * 10.0 / 100, n * 10 / 100.0.
Ето и малко инфо: Binary numeric promotions. Пише, че може да е старо, но няма как да е, тези правила се спазват още от С като изключим, че там няма decimal, byte е char и има long double; т.е. правилата са доста устойчиви.
Приемам отговора на Filkolev за верен. Бях се опитал да конвертивам по следния начин:
(double)(n * 10 / 100) ,което също не даде резултат.
(double)n * 10 / 100 е вярното решение.
(double)(n * 10 / 100) - тук те прецаква приоритетът на операциите. Понеже сметките са оградени със скоби, те се изпълняват първо, смята се резултатът от операции с интове (което пак е инт) и след това този резултат се обръща в double, което няма ефект, дробната част вече е загубена.
Ето това също върши работа: (double)(10)/100; .Макар да не е по-кратко от 10.0/100 или 10/100.0, предложени от теб, е по-красноречиво.
От математиката съм свикнал да очаквам 10/100 винаги да ми дава дробно число. Доста заблуждаващо, но поне сега си изясних нещата.