Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Округление / 25 сообщений из 25, страница 1 из 1
15.10.2015, 10:10
    #39077265
Stanislav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Всем привет!
Есть проблема округления значения в C# и Cи, хотелось бы добиться однозначности при округлении.
Есть значение 7.5077946401986963f в C# =7.507795, а в Си =7,50779486.
Можно ли в C# указать какие-то правила округления для float ?
...
Рейтинг: 0 / 0
15.10.2015, 10:24
    #39077276
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
StanislavЕсть значение 7.5077946401986963f в C# =7.507795
хм
Код: c#
1.
Console.WriteLine(Math.Round(7.5077946401986963f, 8));


7,50779486
...
Рейтинг: 0 / 0
15.10.2015, 10:31
    #39077286
Stanislav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Shocker.ProStanislavЕсть значение 7.5077946401986963f в C# =7.507795
хм
Код: c#
1.
Console.WriteLine(Math.Round(7.5077946401986963f, 8));


7,50779486

хм. Спасибо!
Round я не додумался сделать )
...
Рейтинг: 0 / 0
15.10.2015, 10:35
    #39077296
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
StanislavRound я не додумался сделатьStanislavЕсть проблема округления значенияа что тогда подразумевается под округлением?
...
Рейтинг: 0 / 0
15.10.2015, 10:40
    #39077307
Stanislav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Shocker.ProStanislavRound я не додумался сделатьStanislavЕсть проблема округления значенияа что тогда подразумевается под округлением?
Debug.WriteLine(7.5077946401986963f);
...
Рейтинг: 0 / 0
15.10.2015, 10:49
    #39077320
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Ну то есть ты фактически делаешь ToString()
Ему тоже можно задать параметры форматирования строки
...
Рейтинг: 0 / 0
15.10.2015, 10:58
    #39077333
Stanislav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Shocker.ProНу то есть ты фактически делаешь ToString()
Ему тоже можно задать параметры форматирования строки
Получатся если так
Код: c#
1.
Debug.WriteLine(7.5077946401986963f); 

тип
Код: c#
1.
float


а так
Код: c#
1.
Console.WriteLine(Math.Round(7.5077946401986963f, 8));

тип
Код: c#
1.
double
...
Рейтинг: 0 / 0
15.10.2015, 11:16
    #39077367
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Нет. В обоих случаях тип String

Просто не используй неявные преобразования, и будет тебя щастье
...
Рейтинг: 0 / 0
15.10.2015, 11:33
    #39077398
Stanislav
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Shocker.ProНет. В обоих случаях тип String

Просто не используй неявные преобразования, и будет тебя щастье
да string, но в одном случае он получился через float в другом через double.
...
Рейтинг: 0 / 0
15.10.2015, 11:55
    #39077434
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
StanislavShocker.ProНет. В обоих случаях тип String

Просто не используй неявные преобразования, и будет тебя щастье
да string, но в одном случае он получился через float в другом через double.
если нужна большая точность чем double, используйте decimal, для float методов у Math нет
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
26.06.2018, 12:11
    #39665905
fortibransa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Гыыыыы
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
        static void Main(string[] args)
        {
            double[] values = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 };
            foreach (double value in values)
                Console.WriteLine("{0}   AwayFromZero --> {1}   ToEven --> {2} string.Format(\"F:2\") --> {0:F2}", value,
                                  Math.Round(value, 2, MidpointRounding.AwayFromZero),  Math.Round(value, 2, MidpointRounding.ToEven));
            Console.ReadLine();
        }



Результат:

2,125 AwayFromZero --> 2,13 ToEven --> 2,12 string.Format("F:2") --> 2,13
2,135 AwayFromZero --> 2,13 ToEven --> 2,13 string.Format("F:2") --> 2,14
2,145 AwayFromZero --> 2,15 ToEven --> 2,14 string.Format("F:2") --> 2,15
3,125 AwayFromZero --> 3,13 ToEven --> 3,12 string.Format("F:2") --> 3,13
3,135 AwayFromZero --> 3,14 ToEven --> 3,14 string.Format("F:2") --> 3,14
3,145 AwayFromZero --> 3,15 ToEven --> 3,14 string.Format("F:2") --> 3,15
...
Рейтинг: 0 / 0
26.06.2018, 12:20
    #39665915
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
double это представление с погрешностью, т.е. 2,135 может быть в реале 2.13499999999999999999999999999

используй decimal
...
Рейтинг: 0 / 0
26.06.2018, 12:23
    #39665917
fortibransa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Dima Tdouble это представление с погрешностью, т.е. 2,135 может быть в реале 2.13499999999999999999999999999

используй decimalОказывается по поводу этих 2.135, чуть ли ни диссертации написаны.
...
Рейтинг: 0 / 0
26.06.2018, 13:04
    #39665964
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
fortibransa,

с этой проблемой борются с тех времен, как научились представлять дробные числа в виде мантиссы и экспоненты. В результате чего, у значения типа double или float всегда есть хвостик, который надо учитывать.
С этим не нужно бороться, просто нужно не забывать об этом. В том числе и то, что 2 равных на 1 взгляд числа с типом double могут оказаться далеко не одним и тем же.
...
Рейтинг: 0 / 0
26.06.2018, 13:05
    #39665965
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
YouTube Video
...
Рейтинг: 0 / 0
26.06.2018, 14:23
    #39666034
fortibransa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Roman Mejtesfortibransa,

с этой проблемой борются с тех времен, как научились представлять дробные числа в виде мантиссы и экспоненты. В результате чего, у значения типа double или float всегда есть хвостик, который надо учитывать.
С этим не нужно бороться, просто нужно не забывать об этом. В том числе и то, что 2 равных на 1 взгляд числа с типом double могут оказаться далеко не одним и тем же.Для этого в Round специально есть эта хрень MidpointRounding.AwayFromZero

Что ты мне лекции читаешь, но она на 2.135 лажает, а стринг формат нет? Мне заказчики серьезные вопросы задают, почему в логе на экране такая цифра, а сохраняется другая.
...
Рейтинг: 0 / 0
26.06.2018, 15:23
    #39666077
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
fortibransaа стринг формат нет?
тоже не идеален
Код: c#
1.
2.
Double x = 2.135;
Console.WriteLine("{0} {0:F2} {1} {1:F2}", x, x-2.13);


Результат
Код: plaintext
2,135 2,14 0,00499999999999989 0,00

ИМХО Как вариант можно перед округлением делать +0.001*минимальная разрядность, т.е. прибавлять значение больше погрешности, в этом случае будет гарантия что реальное значение чуть больше.
Например если нужна точность до сотых, то
Код: c#
1.
Math.Round(x + 0.00001, 2)
...
Рейтинг: 0 / 0
26.06.2018, 20:28
    #39666209
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
fortibransa,
в данном случае Round не виноват))

Поскольку бесконечное множество вещественных чисел отображается на конечное множество чисел диапазона того или иного типа (float/double/decimal) ошибки точности представления чисел неизбежны. Конечно, для decimal, при вдвое большем размере и меньшем диапазоне, они будут существенно меньше (незаментней) чем для double (и тем более для float).

То, что мы захардкодили double-значение 2.135 и наблюдаем его в отладчике, еще не означает что оно таковым является (для процессора). Вот с помощью этой программы IEEE754 можно посмотреть в какое реальное значение "форматируется" задаваемое.
В нашем случае точное значение 2.1349999999999997868371792719699442386627197265625

Косвенным подтверджением будут результаты в студии:
var xval = 2.135 * 1e17; // 2.1349999999999997E+17
или в отладчике браузера:
2.135 * 1e17: 213499999999999970
...
Рейтинг: 0 / 0
26.06.2018, 20:59
    #39666213
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Вот на этой страничке тоже можно посмотреть "Value actually stored in float" (для double нет, но не принципиально).
...
Рейтинг: 0 / 0
27.06.2018, 00:05
    #39666249
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
LRfortibransa,
в данном случае Round не виноват))

Поскольку бесконечное множество вещественных чисел отображается на конечное множество чисел диапазона того или иного типа (float/double/decimal) ошибки точности представления чисел неизбежны. Конечно, для decimal, при вдвое большем размере и меньшем диапазоне, они будут существенно меньше (незаментней) чем для double (и тем более для float).

То, что мы захардкодили double-значение 2.135 и наблюдаем его в отладчике, еще не означает что оно таковым является (для процессора). Вот с помощью этой программы IEEE754 можно посмотреть в какое реальное значение "форматируется" задаваемое.
В нашем случае точное значение 2.1349999999999997868371792719699442386627197265625

Косвенным подтверджением будут результаты в студии:
var xval = 2.135 * 1e17; // 2.1349999999999997E+17
или в отладчике браузера:
2.135 * 1e17: 213499999999999970
я кинул ссылку автору на лекцию из MIT, но он не хотел, не читать, не смотреть, думаю до него и так не дойдет. Ему просто "надо", а как, не его проблемы. Хочет заставить компьютер работать ,но при этом не хочет знать как он работает =)
...
Рейтинг: 0 / 0
27.06.2018, 00:43
    #39666255
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Roman Mejtesна лекцию из MIT
Спасибо за ссылку, чудесная лекция, потрясающий препод))

Кстати, "полагаясь на print" тоже можно было бы ухватить суть проблемы (G9/G17 - "максимальный" вывод):
System.Diagnostics.Debug.WriteLine($"2.135f={2.135f:G8}(G8)={2.135f:G9}(G9), 2.135d={2.135d:G16}(G16)={2.135d:G17}(G17)");
----------
2.135f=2.135(G8)=2.13499999(G9), 2.135d=2.135(G16)=2.1349999999999998(G17)
...
Рейтинг: 0 / 0
27.06.2018, 07:03
    #39666278
fortibransa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Roman MejtesLRfortibransa,
в данном случае Round не виноват))

Поскольку бесконечное множество вещественных чисел отображается на конечное множество чисел диапазона того или иного типа (float/double/decimal) ошибки точности представления чисел неизбежны. Конечно, для decimal, при вдвое большем размере и меньшем диапазоне, они будут существенно меньше (незаментней) чем для double (и тем более для float).

То, что мы захардкодили double-значение 2.135 и наблюдаем его в отладчике, еще не означает что оно таковым является (для процессора). Вот с помощью этой программы IEEE754 можно посмотреть в какое реальное значение "форматируется" задаваемое.
В нашем случае точное значение 2.1349999999999997868371792719699442386627197265625

Косвенным подтверджением будут результаты в студии:
var xval = 2.135 * 1e17; // 2.1349999999999997E+17
или в отладчике браузера:
2.135 * 1e17: 213499999999999970
я кинул ссылку автору на лекцию из MIT, но он не хотел, не читать, не смотреть, думаю до него и так не дойдет. Ему просто "надо", а как, не его проблемы. Хочет заставить компьютер работать ,но при этом не хочет знать как он работает =)Родной, я знаю как он работает и без лекций того чувачка, лекции и сам могу почитать.
...
Рейтинг: 0 / 0
28.06.2018, 11:04
    #39667016
vlsaf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Что-то затормозил. Есть число 1.299999999. Как сделать округление до 3-х знаков после запятой, но если после округления получили, например, "1.300", то показывало бы "1.3".
Т.е. незначащие нули отсекались бы. Все это нужно сделать, используя строки стандартных числовых форматов. Типа "F3" или "G3".
...
Рейтинг: 0 / 0
28.06.2018, 11:14
    #39667021
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
vlsaf,

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
> string.Format("{0:0.###}", 1.555555555)
"1,556"
> string.Format("{0:0.###}", 1.333333333)
"1,333"
> string.Format("{0:0.###}", 1.3)
"1,3"
> string.Format("{0:0.###}", 123123123.123123123)
"123123123,123"
> 
...
Рейтинг: 0 / 0
28.06.2018, 11:19
    #39667025
vlsaf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Округление
Благодарю!
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Округление / 25 сообщений из 25, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]