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
ybaltova avatar ybaltova 14 Точки

Още едно предложение на решение с double и от мен:

Console.WriteLine("Enter a number:");
        double a = double.Parse(Console.ReadLine());
        Console.WriteLine("Enter another number you would like to compare to the first one:");
        double b = double.Parse(Console.ReadLine());

        if (Math.Abs(a - b) < 0.000001)
        {
            Console.WriteLine("The numbers are equal.");
        }
        else
        {
            Console.WriteLine("The numbers are not equal.");
        }

1
koleto_pz avatar koleto_pz 28 Точки

 На повечето решения тука не се постига правилно сравнение на (примерно) 0,1 и -0,1, също и често -4.999999 ? -4.999998 = false не става.  Работя по въпроса.

П. С. Ето моето решение, с всичко работещо и повишена дуракоустойчовост :D

https://github.com/NNNikolov/Home_Works_CSharp_SoftUni/blob/master/Primitive-Data-Types-and-Variables-Homework/13.ComparingFloats/ComparingFloats.cs

0
scr33nsh0o7 avatar scr33nsh0o7 61 Точки

според мен трябва да обърнеш eps в отрицателно само когато а и b са по малки от 0, аз така го направих и се получи

0
scr33nsh0o7 avatar scr33nsh0o7 61 Точки

моето решение е доста дълго, но работи перфектно.. поне според тестовете, които направих laughing

ComparingFloats

дайте мнение моля :)

0
Nexus avatar Nexus 119 Точки

Още едно решение:

 

Console.WriteLine("Please enter first Number");
decimal a = decimal.Parse(Console.ReadLine());
Console.WriteLine("Please enter second Number");
decimal b = decimal.Parse(Console.ReadLine());
decimal eps = 0.000001M;
decimal result = a - b;
bool sum = (a - b) < eps;
if (a < b)
{
sum = eps > (b - a);
}
Console.WriteLine("Are these numbers equal with precision = 0.000001 - " + sum);
Console.WriteLine("The result is: " + result);

0
Filkolev avatar Filkolev 4482 Точки

Само една вметка - идеята на задачата е да се сравняват floating-point числа, т.е. преднамерено се иска да ползваме float/double и тях да ги сравним по някакъв начин. Защото с decimal този проблем не стои, там директно може да сравним две числа и ще знаем, че отговорът е верен, понеже няма закръгляния.

И препоръка - може да се улесни алгоритъма ако ползваш Math.abs, за да вземеш абсолютната стойност на разликата и да я сравниш с епсилона, така няма нужда от проверки.

2
Nexus avatar Nexus 119 Точки

Благодаря ,

 

За Math.abs видях в тази тема и хубаво, че я разгледах. Полезна е ...

0
tr31ze avatar tr31ze 5 Точки

Ето едно спретнато решение. Вкарвам всички числа в масив и ги обхождам с цикъл. Без излишни редове.


double[] doubleA = { 5.3, 5.00000001, 5.00000005, -0.0000007, -4.999999, 4.999999 };
double[] doubleB = { 6.01, 5.00000003, 5.00000001, 0.00000007, -4.999998, 4.999998 };
for (int i = 0; i < doubleA.Length; i++)
{
     if (Math.Abs(doubleA[i] - doubleB[i]) < 0.000001)
     {
     Console.WriteLine("{0} equals {1}", doubleA[i], doubleB[i]);
     }
     else
     {
     Console.WriteLine("{0} not equal to {1}", doubleA[i], doubleB[i]);
}
}

0
charlottka1 avatar charlottka1 0 Точки

 

ето го и моето решение, до което стигнах след дълго ровене в нета.. надявам се да е вярно? 

п.с. с float ми дава грешка, точно защото е до 7-я знак, и като повечето колеги, смятам че е удачно използването на double :)

static void Main()
{
double eps = 0.000001;
double a = 3.4;
double b = 4.01;
bool equalAB = Math.Abs(a - b) < eps; // we can use also 1e-6; // 1x10^-6 = 0.000001
Console.WriteLine("Are those numbers equal: {0} and {1} ? {2}", a, b, equalAB);
}

0
09/11/2014 12:31:32
metodiev37 avatar metodiev37 2 Точки

Линка не се отваря.

 

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