Loading...
Angmar avatar Angmar 1 Точки

Много странен казус

Дълго е да описвам как стигнах до този резултат, но е в опитите ми да реша проста задача от курса Programing Baiscs. Проблема е че при елементарно умножение Visual Studio вади не верни резултати:

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            double quantity = double.Parse(Console.ReadLine());
            Console.WriteLine(quantity * 6);
        }
    }
}
 

При въвеждане на 1.2 би трябвало да вади 7.2 но вади абсурден резултат от 7.1989999 и т.н. някаква идея защо?

Тагове:
0
Programming Basics with C#
nickwork avatar nickwork 657 Точки
Best Answer

Проблема се решава по този начин , като >>f1<< определя броя на цифрите след десетичната запетая...ако искаш да са две напиши f2....за три f3...Относно защо работи така по добре прочети малко сам в инет - double type precision in C#

Console.WriteLine($"{(quantity * 6):f1}");

Другият вариант е да ползваш направо decimal за по голяма точност

0
04/04/2020 14:17:19
Angmar avatar Angmar 1 Точки

Да прочетох, но малко не ми стана ясно.... ако става дума за някаква сериозна прецизност бих разбрал но за 6 * 1.2  e абсурдно, пък и judge поради това ми връща грешка, а за decimal още не сме учили и съм малко параграф 22. Кода като логика би трябвало да работи но ми връща грешки заради точността на вида променлива?!

0
nickwork avatar nickwork 657 Точки

Пусни ми някакво условие на задачата и ще ти я разясня....сори че те занимвам с работи които не сте взели още :)

 

Грешки при пресмятания с реални типове При пресмятания с реални типове данни с плаваща запетая е възможно да наблюдаваме странно поведение, тъй като при представянето на дадено реално число много често се губи точност. Причината за това е невъзмож ността някои реални числа да се представят точно сума от отрицателни степени на числото 2. Примери за числа, които нямат точно представяне в типовете float и double, са например 0.1, 1/3, 2/7 и други. Следва примерен C# код, който демонстрира грешките при пресмятания с числа с плаваща запетая в C#: float f = 0.1f; Console.WriteLine(f); // 0.1 (correct due to rounding) double d = 0.1f; Console.WriteLine(d); // 0.100000001490116 (incorrect) float ff = 1.0f / 3; Console.WriteLine(ff); // 0.3333333 (correct due to rounding) double dd = ff; Console.WriteLine(dd); // 0.333333343267441 (incorrect) Причината за неочаквания резултат в първия пример е фактът, че числото 0.1 (т.е. 1/10) няма точно представяне във формата за реални числа с плаваща запетая IEEE 754 и се записва в него с приближение. При непо средствено отпечатване резултатът изглежда коректен заради закръглява нето, което се извършва скрито при преобразуването на числото към стринг. При преминаване от float към double грешката, получена заради приближеното представяне на числото в IEEE 754 формат става вече явна и не може да бъде компенсирана от скритото закръгляване при отпечатва нето и съответно след осмата значеща цифра се появяват грешки. Глава 2. Примитивни типове и променливи 123 При втория случай числото 1/3 няма точно представяне и се закръглява до число, много близко до 0.3333333. Кое е това число се вижда отчетливо, когато то се запише в типа double, който запазва много повече значещи цифри. И двата примера показват, че аритметиката с числа с плаваща запетая може да прави грешки и по тази причина не е подходяща за прецизни финансови пресмятания. За щастие C# поддържа аритметика с десетична точност, при която числа като 0.1 се представят в паметта без закръгляне. Не всички реални числа имат точно представяне в типо вете float и double. Например числото 0.1 се представя закръглено в типа float като 0.099999994. Реални типове с десетична точност В C# се поддържа т. нар. десетична аритметика с плаваща запетая (decimal floating-point arithmetic), при която числата се представят в десетична, а не в двоична бройна система и така не се губи точност при записване на десетично число в съответния тип с плаваща запетая. Типът данни за реални числа с десетична точност в C# е 128-битовият тип decimal. Той има точност от 28 до 29 десетични знака. Минималната му стойност е -7.9×1028, а максималната е +7.9×1028. Стойността му по подразбиране е 0.0м или 0.0М. Символът 'm' накрая указва изрично, че числото е от тип decimal (защото по подразбиране всички реални числа са от тип double). Най-близките до 0 числа, които могат да бъдат записани в decimal са ±1.0 × 10-28. Видно е, че decimal не може да съхранява много големи положителни и отрицателни числа (например със стотици цифри), нито стойности много близки до 0. За сметка на това този тип почти не прави грешки при финансови пресмятания, защото представя числата като сума от степени на числото 10, при което загубите от закръгляния са много по-малки, отколкото когато се използва двоично представяне. Реалните числа от тип decimal са изключително удобни за пресмятания с пари – изчисляване на приходи, задължения, данъци, лихви и т.н. Следва пример, в който декларираме променлива от тип decimal и й присвояваме стойност: decimaldecimalPI=3.14159265358979323846m;Console.WriteLine(decimalPI); // 3.14159265358979323846 Числото decimalPI, което декларирахме от тип decimal, не е закръглено дори и с един знак, тъй като го зададохме с точност 21 знака, което се побира в типа decimal без закръгляне. 124 Въведение в програмирането със C# Много голямата точност и липсата на аномалии при пресмятанията (каквито има при float и double) прави типа decimal много подходящ за финансови изчисления, където точността е критична. Въпреки по-малкия си обхват, типът decimal запазва точ ност за всички десетични числа, които може да побере! Това го прави много подходящ за прецизни сметки, най често финансови изчисления. Основната разлика между реалните числа с плаваща запетая реалните числа с десетична точност е в точността на пресмятанията и в степента, до която те закръглят съхраняваните стойности. Типът double позволява работа с много големи стойности и стойности много близки до нулата, но за сметка на точността и неприятни грешки от закръгляне. Типът decimal има по-малък обхват, но гарантира голяма точност при пресмятанията и липсва на аномалии с десетичните числа. decimal, а не float или double. В противен случай може да се натъкнете на неприятни аномалии при пресмятанията и Ако извършвате пресмятания с пари използвайте типа грешки в изчисленията! Тъй като всички изчисления с данни от тип decimal се извършват чисто софтуерно, а не директно на ниско ниво в микропроцесора, изчисленията с този тип са от няколко десетки до стотици пъти по-бавни, отколкото същите изчисления с double, така че ползвайте този тип внимателно.

0
Angmar avatar Angmar 1 Точки

Това е кода който ми прави проблем при въвъждане от конзолата на

water

Plovdiv

3

би трябвало да излезе 2.1, а VS вади 2.0999999999999996  и се опитах да парсна decimal ама ми дава грешка в синтаксиса :(

 

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            string product = Console.ReadLine();
            string city = Console.ReadLine();
            double amount = double.Parse(Console.ReadLine());
            double price = 0;
            // Main variable definition

            if (city == "Sofia")
            {
                switch (product)
                {
                    case "coffee":
                        price = 0.50;
                        break;
                    case "water":
                        price = 0.80;
                        break;
                    case "beer":
                        price = 1.20;
                        break;
                    case "sweets":
                        price = 1.45;
                        break;
                    case "peanuts":
                        price = 1.60;
                        break;
                    default:
                        Console.WriteLine("error");
                        break;
                }
                double total = price * amount;
                Console.WriteLine(total);
            }
            else if (city == "Plovdiv")
            {
                switch (product)
                {
                    case "coffee":
                        price = 0.40;
                        break;
                    case "water":
                        price = 0.70;
                        break;
                    case "beer":
                        price = 1.15;
                        break;
                    case "sweets":
                        price = 1.30;
                        break;
                    case "peanuts":
                        price = 1.50;
                        break;
                    default:
                        Console.WriteLine("error");
                        break;
                }
                double total = price * amount;
                Console.WriteLine(total);
            }
            else if (city == "Varna")
            {
                switch (product)
                {
                    case "coffee":
                        price = 0.45;
                        break;
                    case "water":
                        price = 0.70;
                        break;
                    case "beer":
                        price = 1.10;
                        break;
                    case "sweets":
                        price = 1.35;
                        break;
                    case "peanuts":
                        price = 1.55;
                        break;
                    default:
                        Console.WriteLine("error");
                        break;
                }
                double total = price * amount;
                Console.WriteLine(total);
            }
            else
            {
                Console.WriteLine("error");
            }

        }
    }
}

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