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
svetli0o avatar svetli0o 134 Точки

Моята задача без decimal

http://pastebin.com/3h8x7u50

1
TodorovH avatar TodorovH 216 Точки

Струва ми се малко усложнена и трудна за четене, може да е по-кратка и универсална за смятане по зададени данни! Ето моето решение, моля за мнение и препоръки! Има редове, които съм добавил само за да се визуализира по-добре, иначе може и по-кратко!

http://pastebin.com/4WCeLW5X

Успех!

0
beBoss avatar beBoss 507 Точки

Май доста сте задълбали на тази задача :) Идеята и е, да разберете, че float реже до 7-я знак след точката и общовзето това е. Затова задачата, разбира се може по няколко варианта да се направи, но с double е най-удачно. Разбира се ако се търси сигурност в сметките винаги може да се ползва decimal, но той е бавен и в случая не е нужен.

Ето едно решение, което може да е полезно на някой:

------------------------------------------------------------------

using System;

class CompareFloatingPointNumbers
{
    static void Main()
    {
        Console.Write("Enter the first number: ");
        double firstNumber = double.Parse(Console.ReadLine());
        Console.Write("Enter the second number: ");
        double secondNumber = double.Parse(Console.ReadLine());
        float precision = 0.000001f;
        bool areEqual = (Math.Abs(firstNumber - secondNumber) < precision);
        Console.WriteLine(areEqual);
    }
} 

5
TodorovH avatar TodorovH 216 Точки
По-малко или равно не отговаря на условието на задачата!
0
beBoss avatar beBoss 507 Точки
Да, леко недоглеждане. Поправено е.
2
ViValDam avatar ViValDam 15 Точки

Math.Abs(firstNumber - secondNumber) ,не е правилният израз !

Ако имаш например първи номер = 7 и втори равен = -7 , какво става ? 7-(-7) =14 или -7-(-3) ще ги събере ,вместо да ги извади !__

1
ViValDam avatar ViValDam 15 Точки

Моето решение на задачата :

decimal numberOne;
decimal numberTwo;
decimal difference = 0;
decimal eps = 0.000001m;
bool equal = true;

Console.WriteLine("Please, use a decimal point, do not use comma!");
Console.WriteLine();
Console.WriteLine("Enter number one:");
Console.WriteLine();
string line = Console.ReadLine(); 

if (decimal.TryParse(line, out numberOne)) 
{
Console.WriteLine();
Console.WriteLine("Enter number two:");
Console.WriteLine(
);
line = Console.ReadLine();

if (decimal.TryParse(line, out numberTwo)) 
{
difference = Math.Abs (Math.Abs(numberOne) - Math.Abs(numberTwo)) ;
Console.WriteLine("This numbers difference is " + difference);
Console.WriteLine();

if (difference >= eps)
{
equal = !equal;
}

if (equal)
{
Console.WriteLine("Thus, " + numberOne + " and " + numberTwo + " are equal numbers.");
}
else  // not equal
{
Console.WriteLine("Thus, " + numberOne + " and " + numberTwo + " are not an equal numbers.");
}
}
else
{
Console.WriteLine("Wrong input for number two!");
}
}
else
{
Console.WriteLine("Wrong input for number one!");
}









































2
GeorgeK avatar GeorgeK 0 Точки

Защо като използвам "." за разделяне ми дава грешка, а като изпозлзвам "," всичко е коректно и си смята правилно ?!

Това ми е програмката :

using System;
 

    class ComparingFloats
    {
        static void Main()
        {
            Console.Write("first num = ");
            decimal firstNum = decimal.Parse(Console.ReadLine());
            Console.Write("second num = ");
            decimal secondNum =  decimal.Parse(Console.ReadLine());
            decimal diff = Math.Abs(firstNum - secondNum);
            decimal eps = 0.000001M;
            bool compare = ( diff < eps);
            Console.WriteLine(compare);


        }
    }

0
ViValDam avatar ViValDam 15 Точки

Защо едното float , а другото double ?

Ползвай един тип - най-добре - decimal !

0
ViValDam avatar ViValDam 15 Точки

Не е задължително числата на потребителя да са флот !

Просто на английски флотинг поинт нъмбер се превежда буквално - число с плаваща запетая  -на български.

Най-добре ,като се работи с такива числа е да се ползва типа дицимал - единственно той не дава грешки ! Така каза и Наков в лекцията му за академията"Терелик".

0
ViValDam avatar ViValDam 15 Точки

Всички имате една и съща грешка - изразът ви за изваждането на 2-те числа е неправилен !

Проверете , какво става , когато второто число е отрицателно !

Освен това , числата с плаваща запетая на английски - флотинг поинт нъмбърс - могат да бъдат от който си искате от трите типа за тях  - флот, дабъл или децимал - учете английски , както казва Наков !

Ако не се сещате за правилният израз за изваждането - вижте го в моето решение .

Ама първо помислете сами !

1
TodorovH avatar TodorovH 216 Точки

Всички първоначално използват float понеже заглавието на задачата е ComparingFloats, но после явно от проверките става ясно, че не работи с всички примери правилно!

Изискването на задачата е по-просто от твоето решение, изисква се при зададени данни за а и в да се изпечата булева променлива, което става с код от 5-6 реда!

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

Вива,

Права си, че Math.Abs(firstNum-secNum) е различно от Math.Abs(Math.abs(firstNum) - Math.Abs(secNum)), но според мен именно използвайки втория израз допускаш неточност. Рънни пример с 1 и -1, имаш:

Math.Abs(Math.abs(1)-Math.abs(-1)) = Math.Abs(1-(+1) )= 0, така като краен резултат програмата ще ти даде, че двете числа са равни, а те не са - имат различен знак.

1
patrik avatar patrik 26 Точки

Това е моя резултат:

using System;

namespace ComparingFloats
{
    class ComparingFloats
    {
        static void Main(string[] args)
        {
            decimal  eps = 0.000001m;
            Console.WriteLine("Please enter two numbers:");
            Console.WriteLine("Enter a= ");
            decimal a = decimal.Parse(Console.ReadLine());
            Console.WriteLine("Enter b= ");
            decimal b = decimal.Parse(Console.ReadLine());
            decimal result = Math.Abs(a - b);
                if (result > eps)
           {
               Console.WriteLine("The difference of {0} is too big  ", result);
               Console.WriteLine("false");
           }
           if (result < eps)
           {
               Console.WriteLine("The difference {0} < eps",result);
               Console.WriteLine("true");
           }
           if (result == eps)
           {
               Console.WriteLine("Border case. The difference {0} == eps. We consider the numbers are different.", result);
               Console.WriteLine("false");
           }
          
          
       }
    }
}


Виждам че почти всички сте използвали булев израз грешно ли е ако не се използва?

0
ZvetanIG avatar ZvetanIG 907 Точки

Вярно е, че decimal забавя изпълнението на програмата, но вслучая в програма с две - три променливи и няколко операции с тях това забавяне ще е никакво.  В задачата трябва променливите да са от този тип. Пуснете програмата пред дебъгера и наблюдавайте променливите и ще видите че при  double и float стойностите не са такива каквито ги очаквате.

0
borispavlov avatar borispavlov 45 Точки

Това е моят код , но дали работи във всички случаи ?


using System;

class ComparingFloats
{
    static void Main()
    {

        Console.WriteLine("Enter first floating number:");
        decimal FirstNumber = Decimal.Parse(Console.ReadLine());
        Console.WriteLine("Enter second floating number:");
        decimal SecondNumber = Decimal.Parse(Console.ReadLine());

        decimal Result = FirstNumber - SecondNumber;
        decimal absResult = Math.Abs(Result);
        decimal eps = 0.000001M;

        if (absResult >= eps)
        {
            Console.WriteLine("These two numbers are not equal (with precision eps=0.000001).");
        }
        else
        {
            Console.WriteLine("These two numbers are equal (with precision eps=0.000001).");
        }
        }
        }


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