Loading...
nikolay.dimov83 avatar nikolay.dimov83 143 Точки

[Homework] C# Basics - Primitive Data Types and Variables - Comparing Floats

Здравейте,

Днес се опитах да реша 3-та задача и се оказа, че е доста по - трудна отколкото изглежда. Проблема е, че когато смятам eps (разликата между двете float числа) и предвиждам да е на граничната стойност 0,000001, системата винаги изчислява стойност за eps близка, но по - малка от 0,000001. Съответно финалния отговор на задачата при гранична стойност става True. В заданието е изрично оказано отговора в граничната стойност да е false. Ако за eps + двете първоначални числа ползвам double (въпреки, че в условието изрично е записано юзърските числа да са float) пак не изчислява коректно eps при зададени числа, така че да се получи гранична стойност 0,000001. Говорих с асистентите, казаха, че ако не се използва decimal, а флоат и double вероятно няма да може да се реши проблема.

Ако все пак някой има идея как да стане без decimal, нека сподели - стана ми  интересно :)

Ето го и кода:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace _03.Comparing_Floats
{
    class Program
    {
        static void Main(string[] args)
        {
            double eps;
            float Num1st;
            float Num2nd;
            string StrNum1st;
            string StrNum2nd;
          
            StrNum1st = Console.ReadLine();
            StrNum2nd = Console.ReadLine();


            if (float.TryParse(StrNum1st, out Num1st) && float.TryParse(StrNum2nd, out Num2nd))
            {
                eps = Math.Abs(Num1st - Num2nd);
                Console.WriteLine(eps);
                bool checkEps;
                if (eps < 0.000001)
                {
                    checkEps = true;
                }
                else
                {
                    checkEps = false;
                }
                Console.WriteLine("The 2 numbers you've enetered is a " + checkEps + " statement");


                
            }
            else
                Console.WriteLine("One of the numbers you entered is not correctly formatted");
 
MOD EDIT: Нарушава т.12 от Правилата на форума! Повече от 15 реда копиран код - моля да го коригирате!
Тагове:
3
Programming Basics 26/09/2014 23:34:28
Anonymous:
Нарушава т.12 и т.2 от Правилата на форума.
Линк към дублираната тема: https://softuni.bg/forum/questions/details/43
nikolay.dimov83 avatar nikolay.dimov83 143 Точки

Май открих решение :

След като изчисля eps и преди проверката дали е по - малко от 0,000001, закръглям до 6-тия знак:

eps = Math.Round(eps, 6, MidpointRounding.AwayFromZero);

1
metodiev37 avatar metodiev37 2 Точки

Просто, кратко и ясно:


            double firstNumber = (double.Parse(Console.ReadLine()));
            double secondNumber = (double.Parse(Console.ReadLine()));
            bool equal = Math.Abs(firstNumber - secondNumber) < 0.000001;
            Console.WriteLine(equal);

1
kalaj1234 avatar kalaj1234 1 Точки

Ахахахах егати цар си браат yes

0
TodorovH avatar TodorovH 216 Точки

По условие имаш стойността на eps = 0.000001 и float смята до 7 знака без да ги закръгля, така че използването на float изпълнява условието за прецизност! Булевите стойностти трябва да са в зависимост от това дали абсолютната стойност на разликата от двете числа а и в е равна или различна от eps! 

И аз съм на нея в момента и си блъскам главата. :)

ПОПРАВКА: Не смята вярно с тоя тип, понеже реже 1-та и дава грешен отговор!

0
wartus avatar wartus 152 Точки

            Console.WriteLine("Add your first number");
            float a = (float.Parse(Console.ReadLine()));
            float b = (float.Parse(Console.ReadLine()));
            bool equalAB = Math.Abs(a - b) < 0.000001;
            Console.WriteLine("Are number {0} and {1} equal? {2}", a, b, equalAB);

Сравняваме абсолютните стойности на числата :) Питайте ако има нещо :))))))))))))))
9
Tr00peR avatar Tr00peR 566 Точки

Колега и аз така го бях направи първоначално, но по този начин не работеше коректно с float. Например последния ред от примерите (4,999999 и 4,999998) връща True, а не трябва. :)

Като смених на double и всичко заспа.

5
Anichka avatar Anichka 93 Точки

Колега Tr00peR, от комбинацията float, "-" и  Math.Abs по принцип можеш да очакваш бели. "-" изглежда се тълкува като допълнителен знак за eps.

           

            double fourthA = -4.999999;//Провери дали не си забравил тук литерал f
            double fourthB = -4.999998;

            if (Math.Abs(fourthA - fourthB) < 0.000001)
            {
                Console.WriteLine(true);
            }
            else
            {
                Console.WriteLine(false);
            }
Това дава false

Заради изписването на конзолата на третата двойка числа(ако не са decimal - -7E-07 и -7E -08), а и изобщо за по-сигурно съм решила задачата ето така

или варианта на wartus, но с double

1
Lyubo avatar Lyubo 172 Точки
Колега в темата за домашно номер две има решение на задачата, може да погледнеш там. Ако обичаш си поправи заглавието на темата, сега човек ще си помисли че имаме трета домашна работа.
2
MarinPetrov avatar MarinPetrov 20 Точки
Здравейте според мен floating-point numbers не означава , че трябва да се ползва float, защото по дефиниция
floating-pоint numbers са числа с плаваща запетая , и тук не се има предвид float, т.е може да бъде както float ,double  така и decimal.
Ето и кода от задачата .

Console.WriteLine("Enter the first number: ");
decimal firstNumber = decimal.Parse(Console.ReadLine());
Console.WriteLine("Enter the second number: ");
decimal secondNumber = decimal.Parse(Console.ReadLine());
bool comparing = (Math.Abs(firstNumber - secondNumber) < 0.000001m);
Console.WriteLine(comparing);





7
gudov avatar gudov 274 Точки
Math.Abs се използва за математически операции на decimal ли?
1
Tr00peR avatar Tr00peR 566 Точки

@gudov

Math.Abs връща модул на числото, може да се използва за всякакви числа. В случая просто ако е отрицателно го прави положително за да може да се сравни.

3
HPetrov avatar HPetrov 822 Точки
Math.Abs върши чудесно работата, но както каза float не е подходящ за всички подадени стойности. В повечето случаи е желателно използването на double и от личен опит мога да кажа, че доста рядко съм използвал float типа. Decimal е доста бавен тип данни и е добре да се използва при случаите, когато имате нужда от доста голяма точност на числата.
0
glava avatar glava 0 Точки
            float a;
            float b;
            decimal rz;
            const decimal eps = 0.000001M;
            a = float.Parse(Console.ReadLine());
            b = float.Parse(Console.ReadLine());
            
            rz = (decimal)a -(decimal)b;
            if (rz < 0) { rz = -rz; }
            if (rz < eps)
            {
                Console.WriteLine("True");   
            }
            else { Console.WriteLine("False"); }
0
nikolay.dimov83 avatar nikolay.dimov83 143 Точки

С decimal на променливите задачата си става отвсякъде.

При използването на float или double гърми при граничните стойности за eps = 0.000001. За тези, които са я решили с double или float променливи, тествайте с такава гранична стойност и сменете подхода като използвате decimal.

Също, можете да си оставите променливите на float/double  и да закръглите eps до 6-ти знак, непосредствено преди да проверите дали абсолютнста му стойност е по - малка от 0,000001.

0
viraldim avatar viraldim 21 Точки

Аз я реших почти по същия начин обаче забелязах 2 неща

- знака на самите числа които се взимат от конзолата не от значение и за това направо им взимам абсолютната стойност.

-след това трябва да направя проверка кое число е по-голямо и да извадя от по-голямото по-малкото за да получа положителна разлика и тогава да я сравня със 0,000001

ето и моето решение http://pastebin.com/dMVbiHgC

0
p.tseperski avatar p.tseperski 21 Точки

Колеги, предлагам ви да ползвате този сайт http://pastebin.com/ за да показвате решението на задачите си. :) Може и GitHub де. Идеята е да се поспестява място тук във форума.

@nikolay.dimov83 

            float Num1st;
            float Num2nd;
            string StrNum1st;
            string StrNum2nd;
          
            StrNum1st = Console.ReadLine();
            StrNum2nd = Console.ReadLine();

променливите трябва да са ти camelCase, а не PascalCase. ;) По принцип де, иначе решението е добро.

0
Roberto avatar Roberto 56 Точки
Днес питах един от асистентите,точно за тази задача и той ми каза,че се решава с Maths.abs , ето ви решение,но по 
.net  , на C#  ще е малко по-различно.
http://stackoverflow.com/questions/3874627/floating-point-comparison-functions-for-c-sharp
0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.