Loading...
YavorSpassov+deleted! avatar YavorSpassov+deleted! 133 Точки

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, но тук имаме различен резултат.


 

 

Тагове:
-1
Programming Basics
IskrenPenev avatar IskrenPenev 177 Точки

n е число от целочислен тип, което ти по-късно умножаваш и делиш отново с целочислени числа (поне ако не сложиш в скоби 10/100), и оттам малко се прецакват нещата.

Има нещо като неписано правило( а може и да го има някъде из документацията):
int * int = int
int / int = int
int * double = double
int / double = double
double / int = double

Вариантите са два: n го parsе-ваш към double, или го кастваш към double:

double n = double.Parse(Console.ReadLine());
-----------или-----------
bonusPoints = (double)n * (10 / 100);

 

-1
31/05/2016 09:39:30
Filkolev avatar Filkolev 4482 Точки

Не е достатъчно. Един израз има тип, който се определя от типовете на променливите, които участват в него.

Изразът 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; т.е. правилата са доста устойчиви.

1
31/05/2016 00:18:29
YavorSpassov+deleted! avatar YavorSpassov+deleted! 133 Точки

Приемам отговора на Filkolev за верен. Бях се опитал да конвертивам по следния начин:
(double)(n * 10 / 100) ,което също не даде резултат. 

(double)n * 10 / 100 е вярното решение.

0
Filkolev avatar Filkolev 4482 Точки

(double)(n * 10 / 100) - тук те прецаква приоритетът на операциите. Понеже сметките са оградени със скоби, те се изпълняват първо, смята се резултатът от операции с интове (което пак е инт) и след това този резултат се обръща в double, което няма ефект, дробната част вече е загубена.

1
KrasimirPetkov avatar KrasimirPetkov 328 Точки

В C# числата, които не са декларирани от даден тип, се приемат автоматично или за int, или за double, в зависимост от начина, по който са записани в програмния код.

Пример:

10 / 4 -> приема се, че 10 е int, 4 също е int и връща резултат 2

10.0 / 4 -> приема се, че 10 е double, 4 e int и резултатът става 2.5

2
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.