Точность double
От: Kazmerchuk Pavel  
Дата: 25.05.21 18:47
Оценка:
#include <cassert>

int main()
{
   double a = 0.014390783999999978;
   double b = 0.052996730719235739;
   double c = a - b; //-0.038605946719235763
   
   assert((b+c) == a); //b+c = 0.014390783999999976
}


Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a? Спасибо.
http://coliru.stacked-crooked.com/a/eb63581b259878aa
Re: Точность double
От: reversecode google
Дата: 25.05.21 18:55
Оценка: -3
long double
Re: Точность double
От: Homunculus Россия  
Дата: 25.05.21 18:57
Оценка: +4
Здравствуйте, Kazmerchuk Pavel, Вы писали:

Забудь про «==« для плавающей точки. Только разницу с эпсилон сравнивай
Re: Точность double
От: LaptevVV Россия  
Дата: 25.05.21 19:02
Оценка:
KP>Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a? Спасибо.
Нет. Даже (со)процессор делает округление.
Тип округления устанавливается в одном из регистров сопроцессора.
без округления выполняются операции со степенями двойки: 1/2 = 2^(-1), 1/4 = 2^(-2) и т.д.
Но и в этом случае выполняется нормализация, при которой младшие разряды результата могут исчезнуть.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Отредактировано 25.05.2021 19:05 LaptevVV . Предыдущая версия .
Re[2]: Точность double
От: watchmaker  
Дата: 25.05.21 19:32
Оценка: +5 :))) :))) :))) :))) :)
Здравствуйте, LaptevVV, Вы писали:

KP>>Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a? Спасибо.

LVV>Даже (со)процессор делает округление.

Да тут даже до процессора дело не всегда доходит.
Компилятор выкидывает ненужные вычисления и заменяет тело функции на прямой вызов assert_fail. Не нужны в машинном коде эти ваши сравнения, если и так всё понятно
Отредактировано 25.05.2021 20:31 watchmaker . Предыдущая версия .
Re[2]: Точность double
От: Kazmerchuk Pavel  
Дата: 25.05.21 19:36
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Нет. Даже (со)процессор делает округление.

А вычислить дополнительную поправку к с, чтобы, например (b + c + correction) == a?
Re: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 25.05.21 19:40
Оценка:
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>
KP>   double a = 0.014390783999999978;
KP>   double b = 0.052996730719235739;
KP>   double c = a - b; //-0.038605946719235763
KP>


KP>Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a? Спасибо.


Нет. double умеет не больше 15ти значащих десятичных знаков хранить, а у тебя — 17. А тут a и b сразу уже хранят не те значения, которые ты им задаёшь. По идее, компилятор должен предупредить об этом, но не факт
Маньяк Робокряк колесит по городу
Re[2]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 25.05.21 19:40
Оценка:
Здравствуйте, reversecode, Вы писали:

R>long double


Который в MSVC, внезапно, тот же double
Маньяк Робокряк колесит по городу
Re[2]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 25.05.21 19:42
Оценка:
Здравствуйте, Homunculus, Вы писали:

H>Забудь про «==« для плавающей точки. Только разницу с эпсилон сравнивай


У меня — можно — https://github.com/al-martyn1/marty_decimal

Маньяк Робокряк колесит по городу
Re[3]: Точность double
От: reversecode google
Дата: 25.05.21 19:47
Оценка:
это или UB или не UB
а какое там представление он имеет в каком компилере до одного места
что то годболд msvс перестал у меня показывать
остальные gcc clang ok
Re: Точность double
От: watchmaker  
Дата: 25.05.21 20:05
Оценка: 4 (1)
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a?

Разница двух double чисел не всегда представима в double без потери точности.
То есть для double ответ — нельзя.

Если необходимо считать точно подобные суммы, то тут поможет только длинная арифметика (с хранением всех значащих бит). Но понятно, что не всегда подходит и всё это довольно далеко от стандартного типа double.


А так, операции в IEEE754 c floating-point не ассоциативные. То есть в них принципиально не выполняется равенство (a + b) + c == a + (b + c).
Нужно с этим уметь жить и писать алгоритмы соответствующим образом.

Например, этот эффект можно учитывать и минимизировать как в алгоритме суммирования Кэхэна. Заметь, что там тоже повторяется похожий паттерн из действий c = a — b; t = b + c; почти как у тебя в примере.

Либо этот эффект можно даже эксплуатировать во благо, например, для быстрого округления чисел без преобразования типов:
double round_pos(double x) {
    const double magic = 0x1p+52;
    return x + magic - magic;
}

Демо: https://godbolt.org/z/d9qexTdWW



Ну и ещё можно упомянуть, что компилятору обычно можно сказать, что он должен считать, что floating-point ассоциативный (например, через ключ -ffast-math в gcc/clang). Тогда он будет генерировать машинный код исходя из предположений, что (a+b)-b можно заменить сначала на a+(b-b), и потом на просто a (да, случай с NaN тоже считается несуществующим). Но не советую идти этой дорогой: тут наоборот сломаются хорошие алгоритмы, которые написаны в рассчёте на гарантии и поведение ieee754. То есть они будут выдавать иногда чушь, но зато работать будет быстро
Отредактировано 25.05.2021 20:44 watchmaker . Предыдущая версия . Еще …
Отредактировано 25.05.2021 20:10 watchmaker . Предыдущая версия .
Отредактировано 25.05.2021 20:06 watchmaker . Предыдущая версия .
Re[4]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 25.05.21 20:17
Оценка: +1
Здравствуйте, reversecode, Вы писали:

R>это или UB или не UB


С чего бы это UB?


R>а какое там представление он имеет в каком компилере до одного места


А это пока ты по граблям не походил
Маньяк Робокряк колесит по городу
Re: Точность double
От: Zhendos  
Дата: 25.05.21 21:28
Оценка: 21 (2)
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>
KP>{
KP>   double a = 0.014390783999999978;
KP>   double b = 0.052996730719235739;
KP>   double c = a - b; //-0.038605946719235763
   
KP>   assert((b+c) == a); //b+c = 0.014390783999999976
KP>}
KP>


можно вычислить ошибку (смотри D. E. Knuth, TAOCP, Vol 2, 4.2.2, Theorem B.):

#include <cassert>

double sum(double u, double v, double& t) {
    double s = u + v;
    double up = s - v;
    double vpp = s - up;
    up -= u;
    vpp -= v;
    t = -(up + vpp);

    return s;
}

int main()
{
    double a = 0.014390783999999978;
    double b = 0.052996730719235739;

    double err;
    const auto c = sum(a, -b, err);

    assert((b+c) + err == a); //b+c = 0.014390783999999976                                                                                                                    
}
Отредактировано 25.05.2021 21:30 Zhendos . Предыдущая версия .
Re[2]: Точность double
От: Kazmerchuk Pavel  
Дата: 26.05.21 09:55
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>Здравствуйте, Kazmerchuk Pavel, Вы писали:


KP>>
KP>>{
KP>>   double a = 0.014390783999999978;
KP>>   double b = 0.052996730719235739;
KP>>   double c = a - b; //-0.038605946719235763
   
KP>>   assert((b+c) == a); //b+c = 0.014390783999999976
KP>>}
KP>>


Z>можно вычислить ошибку (смотри D. E. Knuth, TAOCP, Vol 2, 4.2.2, Theorem B.):


Z>
Z>#include <cassert>

Z>double sum(double u, double v, double& t) {
Z>    double s = u + v;
Z>    double up = s - v;
Z>    double vpp = s - up;
Z>    up -= u;
Z>    vpp -= v;
Z>    t = -(up + vpp);

Z>    return s;
Z>}

Z>int main()
Z>{
Z>    double a = 0.014390783999999978;
Z>    double b = 0.052996730719235739;

Z>    double err;
Z>    const auto c = sum(a, -b, err);

Z>    assert((b+c) + err == a); //b+c = 0.014390783999999976                                                                                                                    
Z>}
Z>



Спасибо! То что нужно!
Re: Точность double
От: PM  
Дата: 26.05.21 20:17
Оценка: 1 (1)
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a? Спасибо.


Еще +0.5 копеек: в статье https://habr.com/ru/post/525090/ сравниваются алгоритмы суммирования Kahan и Rump–Ogita–Oishi
Re[2]: Точность double
От: T4r4sB Россия  
Дата: 26.05.21 20:21
Оценка: +2
Здравствуйте, Zhendos, Вы писали:

Z>можно вычислить ошибку (смотри D. E. Knuth, TAOCP, Vol 2, 4.2.2, Theorem B.):


И даже это ничего не гарантирует
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re: Точность double
От: Vzhyk2  
Дата: 27.05.21 05:29
Оценка: +1
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a? Спасибо.

Можно, но для начала тебе нужно открыть любой учебник по вычислениям на компьютерах и внимательно прочитать и всё поймешь, что можно, что нельзя. Раньше в школе основы оного преподавали. "Значашие цифры", "системы счисления", "периодические и не периодические дроби", "целые, рациональные и иррациональные числа" — это, например, из тех основ.
Re[2]: Точность double
От: Vzhyk2  
Дата: 27.05.21 05:30
Оценка:
Здравствуйте, Homunculus, Вы писали:

H>Забудь про «==« для плавающей точки. Только разницу с эпсилон сравнивай

Чушь. Всё зависит от того, что именно ты хочешь сделать и где.
Re[2]: Точность double
От: Vzhyk2  
Дата: 27.05.21 05:31
Оценка:
Здравствуйте, Marty, Вы писали:

M>Нет. double умеет не больше 15ти значащих десятичных знаков хранить, а у тебя — 17. А тут a и b сразу уже хранят не те значения, которые ты им задаёшь. По идее, компилятор должен предупредить об этом, но не факт

А еще в советской школе рассказывали про погрешности округления и что с ними происходит при вычислениях.
Re[2]: Точность double
От: Vzhyk2  
Дата: 27.05.21 05:34
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Ну и ещё можно упомянуть, что компилятору обычно можно сказать, что он должен считать, что floating-point ассоциативный (например, через ключ -ffast-math в gcc/clang). Тогда он будет генерировать машинный код исходя из предположений, что (a+b)-b можно заменить сначала на a+(b-b), и потом на просто a (да, случай с NaN тоже считается несуществующим). Но не советую идти этой дорогой: тут наоборот сломаются хорошие алгоритмы, которые написаны в рассчёте на гарантии и поведение ieee754. То есть они будут выдавать иногда чушь, но зато работать будет быстро

Это нехорошие алгоритмы, хорошие обычно делают устойчивыми и им пофиг на твои ключики компилятору.
Re[3]: Точность double
От: LaptevVV Россия  
Дата: 27.05.21 07:24
Оценка:
LVV>>Нет. Даже (со)процессор делает округление.
KP>А вычислить дополнительную поправку к с, чтобы, например (b + c + correction) == a?
Надо хорошо разбираться в теории погрешностей — есть такая теория...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 27.05.21 21:39
Оценка:
Здравствуйте, Vzhyk2, Вы писали:

M>>Нет. double умеет не больше 15ти значащих десятичных знаков хранить, а у тебя — 17. А тут a и b сразу уже хранят не те значения, которые ты им задаёшь. По идее, компилятор должен предупредить об этом, но не факт

V>А еще в советской школе рассказывали про погрешности округления и что с ними происходит при вычислениях.

И? Можешь развить свою мысль?
Маньяк Робокряк колесит по городу
Re[2]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 27.05.21 22:03
Оценка: +1
Здравствуйте, Vzhyk2, Вы писали:

KP>>Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a? Спасибо.

V>Можно, но для начала тебе нужно открыть любой учебник по вычислениям на компьютерах и внимательно прочитать и всё поймешь, что можно, что нельзя. Раньше в школе основы оного преподавали. "Значашие цифры", "системы счисления", "периодические и не периодические дроби", "целые, рациональные и иррациональные числа" — это, например, из тех основ.

Не совсем понятно, как ты увязал школьную программу и вычисления на компьютерах. Перечисленное — это основы алгебры, скорее. А системы счисления — если и давали, то в конечных классах
Маньяк Робокряк колесит по городу
Re[2]: Точность double
От: Kazmerchuk Pavel  
Дата: 28.05.21 19:21
Оценка:
Здравствуйте, Vzhyk2, Вы писали:

V>Здравствуйте, Kazmerchuk Pavel, Вы писали:


KP>>Можно ли без округления вычислить c, чтобы гарантировать (b+c) == a? Спасибо.

V>Можно...
Покажи или топик не засоряй
Re[3]: Точность double
От: flаt  
Дата: 28.05.21 20:43
Оценка:
Здравствуйте, Marty, Вы писали:

R>>long double


M>Который в MSVC, внезапно, тот же double


И который в ICC (который, в свою очередь, совместим с MSVC) таки long double (80 bit).
Re[4]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 28.05.21 21:34
Оценка:
Здравствуйте, flаt, Вы писали:

R>>>long double


M>>Который в MSVC, внезапно, тот же double


F>И который в ICC (который, в свою очередь, совместим с MSVC) таки long double (80 bit).


Как совместим? По ключам командной строки?

В итоге-то что? В MSVC long double как-то не превращается в double, или что?

Я еще с борманом наелся этого в прошлом веке, теперь только double и float.
Маньяк Робокряк колесит по городу
Re[5]: Точность double
От: flаt  
Дата: 28.05.21 21:48
Оценка:
Здравствуйте, Marty, Вы писали:

M>Как совместим? По ключам командной строки?


По сорцам (всякие прагмы и прочее) и по ключам командной строки (он как clang, имеет режимы совместимости с GCC и MSVC).

M>В итоге-то что? В MSVC long double как-то не превращается в double, или что?

В ICC — нет, не превращается (но, кажется, там есть ключик и long double может быть как 64, так и 80 бит).
Re[6]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 28.05.21 21:53
Оценка:
Здравствуйте, flаt, Вы писали:

M>>Как совместим? По ключам командной строки?


F>По сорцам (всякие прагмы и прочее) и по ключам командной строки (он как clang, имеет режимы совместимости с GCC и MSVC).


Отлично. Мы разобрались, что ICC совместим с MSVC в командной строке и по сорцам.

Как это отменяет то, что MSVC не умеет в double больше 64х бит?
Маньяк Робокряк колесит по городу
Re[7]: Точность double
От: flаt  
Дата: 28.05.21 22:21
Оценка:
Здравствуйте, Marty, Вы писали:


M>Отлично. Мы разобрались, что ICC совместим с MSVC в командной строке и по сорцам.


M>Как это отменяет то, что MSVC не умеет в double больше 64х бит?


А речь не об отмене. Человек предложил long double, в ответ было сказано, что под MSVC long double не работает (хотя топикстартер платформу не указывал). Но если под MSVC не работает, то есть ещё ICC, который совместим с MSVC.
Re[8]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 28.05.21 23:43
Оценка:
Здравствуйте, flаt, Вы писали:

M>>Отлично. Мы разобрались, что ICC совместим с MSVC в командной строке и по сорцам.


M>>Как это отменяет то, что MSVC не умеет в double больше 64х бит?


F>А речь не об отмене. Человек предложил long double, в ответ было сказано, что под MSVC long double не работает (хотя топикстартер платформу не указывал). Но если под MSVC не работает, то есть ещё ICC, который совместим с MSVC.


Ну и после ICC с другим компилятором у него все поломается. Годный рецепт.
Маньяк Робокряк колесит по городу
Re[3]: Точность double
От: Vzhyk2  
Дата: 29.05.21 04:31
Оценка:
Здравствуйте, Kazmerchuk Pavel, Вы писали:

V>>Можно...

KP>Покажи или топик не засоряй
0001+0001 == 0010.
Re[9]: Точность double
От: pagid Россия  
Дата: 02.06.21 10:19
Оценка:
Здравствуйте, Marty, Вы писали:


M>Ну и после ICC с другим компилятором у него все поломается. Годный рецепт.


Это конечно занятно, про long double, MSVC, ICC и всех, всех, всех... только что это в принципе меняет? Да ничего, ну получится больше значащих цифр, но на них все равно проявятся особенности представления чисел с плавающей точкой.
Ответ другой и очень простой, его Homunculus уже написал.
Re[3]: Точность double
От: pagid Россия  
Дата: 02.06.21 10:27
Оценка:
Здравствуйте, Marty, Вы писали:

M>У меня — можно — https://github.com/al-martyn1/marty_decimal

У тебя на порядок, два, три медленней, оно того не стоит.

И как у тебя сработает?
int main()
{
MartyNumber a = 1.0;
MartyNumber b = a/3;

assert((b+b+b) == a);
}
Отредактировано 02.06.2021 10:36 pagid . Предыдущая версия .
Re[3]: Точность double
От: pagid Россия  
Дата: 02.06.21 10:29
Оценка:
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>А вычислить дополнительную поправку к с, чтобы, например (b + c + correction) == a?

А цель какая?
Re[4]: Точность double
От: Kazmerchuk Pavel  
Дата: 02.06.21 16:38
Оценка:
Здравствуйте, pagid, Вы писали:

P>Здравствуйте, Kazmerchuk Pavel, Вы писали:


KP>>А вычислить дополнительную поправку к с, чтобы, например (b + c + correction) == a?

P>А цель какая?

Решение уже привели. Задача шагать по сеточной функции, точно попадая в узлы. Узлы подвижны.
Re[4]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.06.21 16:57
Оценка:
Здравствуйте, pagid, Вы писали:

M>>У меня — можно — https://github.com/al-martyn1/marty_decimal

P>У тебя на порядок, два, три медленней, оно того не стоит.


Ну, смотря где и как. Домашнюю бухгалтерию вести очень удобно

Медленнее, да — сравнение в 5, сложение и вычитание — в 20, умножение — в 50, про деление вообще не говорю — раз медленнее, чем встроенный double. Но по сравнению с тем же cpp_dec_float из буста — уже не на порядки, а в разы отстаю. И там опять же используется двоичная арифметика.

Но таки очень удобно оказалось. Где скорость не критична, а важна точность — уже перехожу на свой велосипед


P>И как у тебя сработает?

P>int main()
P>{
P> MartyNumber a = 1.0;
P> MartyNumber b = a/3;

P> assert((b+b+b) == a);

P>}

Понятно, что не сработает. У меня для оператора деления используется static поле, содержащее точность. По умолчанию — 18 знаков после точки (при этом не важно, сколько до). Отдельно есть метод div, там точность можно явно задать.

Ясно, что 1/3 в десятичном виде точно не представима.
Но у меня эпсилон для сравнения можно с любым количеством знаков задать в виде строки. И не важно, какого порядка будут величины.

У меня потеря значащих цифр только при делении происходит, все остальные операции, хоть сколько раз складывай/вычитай/умножай — ни одного знака потеряно не будет.

А по поводу правильного сравнения машинных floating point чисел — ну, на диссер конечно тема недотягивает, но там одним эпсилон не отделаешься
Маньяк Робокряк колесит по городу
Re[10]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.06.21 16:59
Оценка:
Здравствуйте, pagid, Вы писали:

P>Ответ другой и очень простой, его Homunculus уже написал.


Слишком простой, тема сравнения плавающих чисел поширше будет. В универе по этим делам вообще два семестра выч мата было, как раз на тему, как считать на double и прочем плавающем
Маньяк Робокряк колесит по городу
Re[4]: Точность double
От: B0FEE664  
Дата: 02.06.21 20:46
Оценка:
Здравствуйте, Vzhyk2, Вы писали:

V>>>Можно...

KP>>Покажи или топик не засоряй
V>0001+0001 == 0010.

А теперь тоже самое для крайне правой десятичной цифры. например, 0.1 + 0.2 = ?
И каждый день — без права на ошибку...
Re[5]: Точность double
От: pagid Россия  
Дата: 03.06.21 04:20
Оценка:
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>Решение уже привели. Задача шагать по сеточной функции, точно попадая в узлы. Узлы подвижны.

Решение с эпсилон проще и эффективнее. Еще можно целочисленную сетку взять. Тоже проще будет.
Re[11]: Точность double
От: pagid Россия  
Дата: 03.06.21 04:21
Оценка:
Здравствуйте, Marty, Вы писали:

M>Слишком простой, тема сравнения плавающих чисел поширше будет. В универе по этим делам вообще два семестра выч мата было, как раз на тему, как считать на double и прочем плавающем

В вопросе ТС нет на два семестра.
Re[5]: Точность double
От: pagid Россия  
Дата: 03.06.21 04:35
Оценка: +1
Здравствуйте, Marty, Вы писали:

M>Ну, смотря где и как. Домашнюю бухгалтерию вести очень удобно

Домашнюю бухгалтерию можно просто вести в копейках.

M>Медленнее, да — сравнение в 5, сложение и вычитание — в 20, умножение — в 50, про деление вообще не говорю — раз медленнее, чем встроенный double. Но по сравнению с тем же cpp_dec_float из буста — уже не на порядки, а в разы отстаю. И там опять же используется двоичная арифметика.

Логично, в компе в принципе используются двоичные вычисления.

M>Но таки очень удобно оказалось. Где скорость не критична, а важна точность — уже перехожу на свой велосипед

Слово "точность" здесь неуместно.

M>Понятно, что не сработает.

Тогда ради чего огород?
Если ради больших чисел не поддерживаемых напрямую процессором, то и их проще и быстрее во всех отношениях сделать двоичными. Или из предположения, что "неудобное" деление не будет использоваться? Тогда проще вести расчеты в двоичных с фиксированной точкой.

M>Но у меня эпсилон для сравнения можно с любым количеством знаков задать в виде строки. И не важно, какого порядка будут величины.

Ну вот, и здесь пришлось эпсилон использовать

M>У меня потеря значащих цифр только при делении происходит, все остальные операции, хоть сколько раз складывай/вычитай/умножай — ни одного знака потеряно не будет.

И это портит всю затею, демонстрируя её бессмысленность.

M>А по поводу правильного сравнения машинных floating point чисел — ну, на диссер конечно тема недотягивает, но там одним эпсилон не отделаешься

Это в самом общем случае, в частных имея представление о задаче, о её "физическом" смысле и о возможных окончательных и промежуточных итогах все проще.
Re[5]: Точность double
От: Vzhyk2  
Дата: 03.06.21 07:23
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>А теперь тоже самое для крайне правой десятичной цифры. например, 0.1 + 0.2 = ?

Я говорил про можно, то бишь существует, а не всегда, то бишь для любых.
А чтобы понимать, почему не для любых достаточно школьной программы.
Re[11]: Точность double
От: Vzhyk2  
Дата: 03.06.21 07:24
Оценка:
Здравствуйте, Marty, Вы писали:

M>Слишком простой, тема сравнения плавающих чисел поширше будет. В универе по этим делам вообще два семестра выч мата было, как раз на тему, как считать на double и прочем плавающем

Что вы 2 семестра делали в университете на выч мате???
Re[12]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.21 09:13
Оценка:
Здравствуйте, Vzhyk2, Вы писали:

M>>Слишком простой, тема сравнения плавающих чисел поширше будет. В универе по этим делам вообще два семестра выч мата было, как раз на тему, как считать на double и прочем плавающем

V>Что вы 2 семестра делали в университете на выч мате???

Считали всякий матан численными методами на компе
Маньяк Робокряк колесит по городу
Re[13]: Точность double
От: Vzhyk2  
Дата: 03.06.21 14:19
Оценка:
Здравствуйте, Marty, Вы писали:

M>Считали всякий матан численными методами на компе

Тогда понятно.

У нас считать на EC1035 было мало. Мы разбирали теорию построения численных методов, что почему и как. Изучали типичные подходы с кучей теорем.
Re[14]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.21 14:24
Оценка:
Здравствуйте, Vzhyk2, Вы писали:

M>>Считали всякий матан численными методами на компе

V>Тогда понятно.

V>У нас считать на EC1035 было мало. Мы разбирали теорию построения численных методов, что почему и как. Изучали типичные подходы с кучей теорем.


Такое тоже было, только я ничего не помню

Без теории, так-то, особого смысла считать нет — хрень насчитаешь, обязательно что-нибудь либо сойдётся не там, где должно, либо разойдётся там, где не должно, и пр
Маньяк Робокряк колесит по городу
Отредактировано 03.06.2021 16:41 Marty . Предыдущая версия .
Re[5]: Точность double
От: · Великобритания  
Дата: 03.06.21 16:17
Оценка:
Здравствуйте, Marty, Вы писали:

M> У меня потеря значащих цифр только при делении происходит, все остальные операции, хоть сколько раз складывай/вычитай/умножай — ни одного знака потеряно не будет.

Тут тоже не всё так просто. Поумножай, скажем 1.00001*1.00001*...*1.00001 миллион раз.. сколько знаков будет? Так что тут нет универсального решения. Где сколько знаков должно диктоваться бизнес-требованиями, я не "правильными" библиотеками.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.21 16:38
Оценка:
Здравствуйте, ·, Вы писали:

M>> У меня потеря значащих цифр только при делении происходит, все остальные операции, хоть сколько раз складывай/вычитай/умножай — ни одного знака потеряно не будет.

·>Тут тоже не всё так просто. Поумножай, скажем 1.00001*1.00001*...*1.00001 миллион раз.. сколько знаков будет? Так что тут нет универсального решения. Где сколько знаков должно диктоваться бизнес-требованиями, я не "правильными" библиотеками.

Ну, я не ограничиваю число знаков при умножении. Так что у меня получится очень много знаков после запятой, на x86 даже адресного пространства не хватит. Тут пользователь — ССЗБ. Если надо много умножать, пусть пользователь округляет сам, метод для этого есть, реализованы практически все виды округления, которые нашел в вики.

Для домашней бухгалтерии же важно, чтобы ни один десятичный знак не пропадал, а деление там — довольно редкая операция, и результаты его обычно используются в качестве вывода, без особого участия в прочих расчётах. Типа купили тут по столько, там по столько, в среднем получилось столько-то за штуку. А ели результат деления и используется в расчётах, то обычно что и как округлять зарегулированно/зарегламентированно.

Но вообще, я и в численных всяких вычислениях попробовал эти десятичные числа использовать, где особо не тороплюсь. И мне понравилось. Одна возможность тупого сравнения без всяких плясок с эпсилон и прочими дорого стоит. Тупо округляем оба числа, например, до 9 знаков после точки, и так же тупо сравниваем. И всё.

Или возможность точного деления с остатком для чисел с плавающей точкой. 1.41 делим на 0.2, на выходе — 7, остаток — 0.01. И всё предельно точно, без каких-либо неявных округлений/усечений и пр. Песня же
Маньяк Робокряк колесит по городу
Re[7]: Точность double
От: · Великобритания  
Дата: 03.06.21 16:46
Оценка:
Здравствуйте, Marty, Вы писали:

M>>> У меня потеря значащих цифр только при делении происходит, все остальные операции, хоть сколько раз складывай/вычитай/умножай — ни одного знака потеряно не будет.

M>·>Тут тоже не всё так просто. Поумножай, скажем 1.00001*1.00001*...*1.00001 миллион раз.. сколько знаков будет? Так что тут нет универсального решения. Где сколько знаков должно диктоваться бизнес-требованиями, я не "правильными" библиотеками.
M>Ну, я не ограничиваю число знаков при умножении. Так что у меня получится очень много знаков после запятой, на x86 даже адресного пространства не хватит. Тут пользователь — ССЗБ. Если надо много умножать, пусть пользователь округляет сам, метод для этого есть, реализованы практически все виды округления, которые нашел в вики.
Ну т.е. опять не универсальный всемогутер, а надо понимать что округлять таки надо.

M>Для домашней бухгалтерии же важно, чтобы ни один десятичный знак не пропадал, а деление там — довольно редкая операция, и результаты его обычно используются в качестве вывода, без особого участия в прочих расчётах. Типа купили тут по столько, там по столько, в среднем получилось столько-то за штуку. А ели результат деления и используется в расчётах, то обычно что и как округлять зарегулированно/зарегламентированно.

В бухгалтерии просто считают в копейках и проблем никаких.

M>Но вообще, я и в численных всяких вычислениях попробовал эти десятичные числа использовать, где особо не тороплюсь. И мне понравилось. Одна возможность тупого сравнения без всяких плясок с эпсилон и прочими дорого стоит. Тупо округляем оба числа, например, до 9 знаков после точки, и так же тупо сравниваем. И всё.

Да ты сравниваешь плавающую и фиксированную точку, разные вещи с разным предназначением. Если ты применял плавучку в ситуации, когда требуется фиксированная точка — ССЗБ.

M>Или возможность точного деления с остатком для чисел с плавающей точкой. 1.41 делим на 0.2, на выходе — 7, остаток — 0.01. И всё предельно точно, без каких-либо неявных округлений/усечений и пр. Песня же

А почему не 7.005 и остаток 0.005? Т.е. у тебя какие-то конкретные требования в твоей конкретной задаче... и ясен пень алгоритм заточенный под конкретные требования лучше. Не вижу о чём тут петь...
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[8]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.21 17:04
Оценка:
Здравствуйте, ·, Вы писали:

M>>Ну, я не ограничиваю число знаков при умножении. Так что у меня получится очень много знаков после запятой, на x86 даже адресного пространства не хватит. Тут пользователь — ССЗБ. Если надо много умножать, пусть пользователь округляет сам, метод для этого есть, реализованы практически все виды округления, которые нашел в вики.

·>Ну т.е. опять не универсальный всемогутер, а надо понимать что округлять таки надо.

Понимать надо, да. Чисто теоретически, конечно можно сделать лимит для умножения, допустим, в несколько тыщь знаков после точки. В принципе, это идея — добавить как опцию.

Но вообще, если человек на C++ пишет — то он всё-таки что-то, хоть краем уха, да слышал и немного понимает


M>>Для домашней бухгалтерии же важно, чтобы ни один десятичный знак не пропадал, а деление там — довольно редкая операция, и результаты его обычно используются в качестве вывода, без особого участия в прочих расчётах. Типа купили тут по столько, там по столько, в среднем получилось столько-то за штуку. А ели результат деления и используется в расчётах, то обычно что и как округлять зарегулированно/зарегламентированно.

·>В бухгалтерии просто считают в копейках и проблем никаких.

Ну, у меня домашняя бухгалтерия — она такая, "домашняя". Как минимум, сотые доли копеек очень в ходу. И проблем там на самом деле выше крыши. Например, "банковское" округление придумали не для того, чтобы на ровном месте новых проблем изобрести.


M>>Но вообще, я и в численных всяких вычислениях попробовал эти десятичные числа использовать, где особо не тороплюсь. И мне понравилось. Одна возможность тупого сравнения без всяких плясок с эпсилон и прочими дорого стоит. Тупо округляем оба числа, например, до 9 знаков после точки, и так же тупо сравниваем. И всё.

·>Да ты сравниваешь плавающую и фиксированную точку, разные вещи с разным предназначением. Если ты применял плавучку в ситуации, когда требуется фиксированная точка — ССЗБ.

Ну, у меня я бы не сказал, что точка фиксированная. Вполне себе плавает. Фикс точка — это когда, например, берем int64_t, и говорим, что младшие 32 бита — дробная часть, старшие — целая часть. У меня вполне себе точка плавающая, просто я не упаковался в фиксированный размер представления. Тут интересно вообще, как такое представление назвать? Не фикс — явно, но и не привычная плавучка — тоже. Надо наверно как-то отдельно называть такой способ представления чисел.


M>>Или возможность точного деления с остатком для чисел с плавающей точкой. 1.41 делим на 0.2, на выходе — 7, остаток — 0.01. И всё предельно точно, без каких-либо неявных округлений/усечений и пр. Песня же

·>А почему не 7.005 и остаток 0.005?

Ну, деление с остатком обычно говорит нам, сколько целых раз делитель содержится в делимом. Да, операция обычно определена для целых, когда и делимое и делитель — целые.

·>Т.е. у тебя какие-то конкретные требования в твоей конкретной задаче... и ясен пень алгоритм заточенный под конкретные требования лучше. Не вижу о чём тут петь...


Домашняя бухгалтерия, она такая


Да и вообще, я просто немного попиарил свой классик, и всё
Маньяк Робокряк колесит по городу
Re[9]: Точность double
От: · Великобритания  
Дата: 03.06.21 17:19
Оценка:
Здравствуйте, Marty, Вы писали:

M>>>Ну, я не ограничиваю число знаков при умножении. Так что у меня получится очень много знаков после запятой, на x86 даже адресного пространства не хватит. Тут пользователь — ССЗБ. Если надо много умножать, пусть пользователь округляет сам, метод для этого есть, реализованы практически все виды округления, которые нашел в вики.

M>·>Ну т.е. опять не универсальный всемогутер, а надо понимать что округлять таки надо.
M>Понимать надо, да. Чисто теоретически, конечно можно сделать лимит для умножения, допустим, в несколько тыщь знаков после точки. В принципе, это идея — добавить как опцию.
M>Но вообще, если человек на C++ пишет — то он всё-таки что-то, хоть краем уха, да слышал и немного понимает
There are exactly 3.00000000000000042 hard things in programming — cache invalidation, naming things, off-by-1 errors and floating point.

M>>>Для домашней бухгалтерии же важно, чтобы ни один десятичный знак не пропадал, а деление там — довольно редкая операция, и результаты его обычно используются в качестве вывода, без особого участия в прочих расчётах. Типа купили тут по столько, там по столько, в среднем получилось столько-то за штуку. А ели результат деления и используется в расчётах, то обычно что и как округлять зарегулированно/зарегламентированно.

M>·>В бухгалтерии просто считают в копейках и проблем никаких.
M>Ну, у меня домашняя бухгалтерия — она такая, "домашняя". Как минимум, сотые доли копеек очень в ходу. И проблем там на самом деле выше крыши. Например, "банковское" округление придумали не для того, чтобы на ровном месте новых проблем изобрести.
Ну в сотых копейках, не важно. Важно что арифметика целочисленная в бухгалтерии.

M>>>Но вообще, я и в численных всяких вычислениях попробовал эти десятичные числа использовать, где особо не тороплюсь. И мне понравилось. Одна возможность тупого сравнения без всяких плясок с эпсилон и прочими дорого стоит. Тупо округляем оба числа, например, до 9 знаков после точки, и так же тупо сравниваем. И всё.

M>·>Да ты сравниваешь плавающую и фиксированную точку, разные вещи с разным предназначением. Если ты применял плавучку в ситуации, когда требуется фиксированная точка — ССЗБ.
M>Ну, у меня я бы не сказал, что точка фиксированная. Вполне себе плавает. Фикс точка — это когда, например, берем int64_t, и говорим, что младшие 32 бита — дробная часть, старшие — целая часть. У меня вполне себе точка плавающая, просто я не упаковался в фиксированный размер представления. Тут интересно вообще, как такое представление назвать? Не фикс — явно, но и не привычная плавучка — тоже. Надо наверно как-то отдельно называть такой способ представления чисел.
Нет, фиксированная точка это когда ты явно хранишь фиксированное число знаков после запятой. Притом знаки могут быть как двоичные (double), так и десятичные (java.lang.BigDecimal или аналог какой-нибудь). А в int64 или byte[] — это уже детали реализации. int64 просто ограничивает тем, что ты не можешь хранить больше, чем 18 десятичных знаков.

M>>>Или возможность точного деления с остатком для чисел с плавающей точкой. 1.41 делим на 0.2, на выходе — 7, остаток — 0.01. И всё предельно точно, без каких-либо неявных округлений/усечений и пр. Песня же

M>·>А почему не 7.005 и остаток 0.005?
M>Ну, деление с остатком обычно говорит нам, сколько целых раз делитель содержится в делимом. Да, операция обычно определена для целых, когда и делимое и делитель — целые.
Ну и остаток определён для целых как правило... А можно и написать что результат 8 и остаток -0.99
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[10]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.21 17:50
Оценка:
Здравствуйте, ·, Вы писали:

M>>Но вообще, если человек на C++ пишет — то он всё-таки что-то, хоть краем уха, да слышал и немного понимает

·>There are exactly 3.00000000000000042 hard things in programming — cache invalidation, naming things, off-by-1 errors and floating point.


А у меня можно и 3.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042 и ничего не потеряется.

Масштаб одной из проблем, согласись, несколько уменьшился, не?

Кстати, а что за проблема "off-by-1 errors"?


M>>·>В бухгалтерии просто считают в копейках и проблем никаких.

M>>Ну, у меня домашняя бухгалтерия — она такая, "домашняя". Как минимум, сотые доли копеек очень в ходу. И проблем там на самом деле выше крыши. Например, "банковское" округление придумали не для того, чтобы на ровном месте новых проблем изобрести.
·>Ну в сотых копейках, не важно. Важно что арифметика целочисленная в бухгалтерии.

Ну они таки делят. Уже известен способ целочисленного деления без потерь знаков?


M>>Ну, у меня я бы не сказал, что точка фиксированная. Вполне себе плавает. Фикс точка — это когда, например, берем int64_t, и говорим, что младшие 32 бита — дробная часть, старшие — целая часть. У меня вполне себе точка плавающая, просто я не упаковался в фиксированный размер представления. Тут интересно вообще, как такое представление назвать? Не фикс — явно, но и не привычная плавучка — тоже. Надо наверно как-то отдельно называть такой способ представления чисел.

·>Нет, фиксированная точка это когда ты явно хранишь фиксированное число знаков после запятой.

Ну, хз. Про фиксированную точку 99% публикаций — о тех случаях, когда точка прибита гвоздями. А оставшийся 1% я не видел


·>Притом знаки могут быть как двоичные (double),


double — это вроде не про фиксированную точку


·>так и десятичные (java.lang.BigDecimal или аналог какой-нибудь). А в int64 или byte[] — это уже детали реализации. int64 просто ограничивает тем, что ты не можешь хранить больше, чем 18 десятичных знаков.


Ну вот я просто и запилил аналог java.lang.BigDecimal. Ни в плюсах, ни в кути — почему-то нет. Хотя вроде Qt умеет в базы данных, а во многих СУБД — NUMBER(M,N) — вполне родной формат. Почему до сих пор не сделали — я хз. Вот я это и исправил, как минимум, для себя.


M>>>>Или возможность точного деления с остатком для чисел с плавающей точкой. 1.41 делим на 0.2, на выходе — 7, остаток — 0.01. И всё предельно точно, без каких-либо неявных округлений/усечений и пр. Песня же

M>>·>А почему не 7.005 и остаток 0.005?
M>>Ну, деление с остатком обычно говорит нам, сколько целых раз делитель содержится в делимом. Да, операция обычно определена для целых, когда и делимое и делитель — целые.
·>Ну и остаток определён для целых как правило... А можно и написать что результат 8 и остаток -0.99

Можно и так считать, да. Поэтому у меня и нету метода mod, а только mod_helper (без учёта знака) — а кому надо, пусть сами допиливают на его базе. Но вообще думаю впилить, так, чтобы вёл себя аналогично целочисленному делению (возвращал всегда целое) и оператору '%' в C++.

С остатком от деления общественность вообще до сих пор не определилась, везде по-разному
Маньяк Робокряк колесит по городу
Re[11]: Точность double
От: · Великобритания  
Дата: 03.06.21 20:49
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, ·, Вы писали:


M>>>Но вообще, если человек на C++ пишет — то он всё-таки что-то, хоть краем уха, да слышал и немного понимает

M>·>There are exactly 3.00000000000000042 hard things in programming — cache invalidation, naming things, off-by-1 errors and floating point.
M>А у меня можно и 3.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042 и ничего не потеряется.
Нигде ничего "не теряется", а отбрасывается. Оно у тебя теряется если ты не понимаешь как оно работает и для чего.

M>Масштаб одной из проблем, согласись, несколько уменьшился, не?

Не.

M>Кстати, а что за проблема "off-by-1 errors"?

https://en.wikipedia.org/wiki/Off-by-one_error

M>>>Ну, у меня домашняя бухгалтерия — она такая, "домашняя". Как минимум, сотые доли копеек очень в ходу. И проблем там на самом деле выше крыши. Например, "банковское" округление придумали не для того, чтобы на ровном месте новых проблем изобрести.

M>·>Ну в сотых копейках, не важно. Важно что арифметика целочисленная в бухгалтерии.
M>Ну они таки делят. Уже известен способ целочисленного деления без потерь знаков?
Целочисленное деление по определению работает без потерь знаков — их там нет, терять нечего.
Например, в налоговой декларации делишь между N участниками — один из них помечается специальным образом, кому идут остатки. Т.е. 100 / 3 == 33 + 33 + 34.

M>>>Ну, у меня я бы не сказал, что точка фиксированная. Вполне себе плавает. Фикс точка — это когда, например, берем int64_t, и говорим, что младшие 32 бита — дробная часть, старшие — целая часть. У меня вполне себе точка плавающая, просто я не упаковался в фиксированный размер представления. Тут интересно вообще, как такое представление назвать? Не фикс — явно, но и не привычная плавучка — тоже. Надо наверно как-то отдельно называть такой способ представления чисел.

M>·>Нет, фиксированная точка это когда ты явно хранишь фиксированное число знаков после запятой.
M>Ну, хз. Про фиксированную точку 99% публикаций — о тех случаях, когда точка прибита гвоздями. А оставшийся 1% я не видел
Как минимум "во многих СУБД — NUMBER(M,N)"? Разве не оно? Или я не понял что значит прибитость гвоздями в твоём понимании.

M>·>Притом знаки могут быть как двоичные (double),

M>double — это вроде не про фиксированную точку
Да, я имел в виду это про двоичную точнку. Тут четые комбинации — плавающая|фиксированая * двоичная|десятичная.

M>·>так и десятичные (java.lang.BigDecimal или аналог какой-нибудь). А в int64 или byte[] — это уже детали реализации. int64 просто ограничивает тем, что ты не можешь хранить больше, чем 18 десятичных знаков.

M>Ну вот я просто и запилил аналог java.lang.BigDecimal. Ни в плюсах, ни в кути — почему-то нет. Хотя вроде Qt умеет в базы данных, а во многих СУБД — NUMBER(M,N) — вполне родной формат. Почему до сих пор не сделали — я хз. Вот я это и исправил, как минимум, для себя.
https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[12]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.21 21:21
Оценка:
Здравствуйте, ·, Вы писали:


M>>А у меня можно и 3.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042 и ничего не потеряется.

·>Нигде ничего "не теряется", а отбрасывается. Оно у тебя теряется если ты не понимаешь как оно работает и для чего.

У меня ничего не теряется и не "отбрасывается". Умножь 123456789012345678901234567890.12345678901234567890 на 0.000000000000000000000000000000000000000000000000000000000000001

Я могу получить точный результат, а ты — нет.


M>>Масштаб одной из проблем, согласись, несколько уменьшился, не?

·>Не.

Вай?


M>>Кстати, а что за проблема "off-by-1 errors"?

·>https://en.wikipedia.org/wiki/Off-by-one_error

А...
Но вообще-то можно было привести ссылку на русскую вики. Или даже словами рассказать. Проблема старая, да, а с итераторами ещё сложнее становиться.


·>Целочисленное деление по определению работает без потерь знаков — их там нет, терять нечего.

·>Например, в налоговой декларации делишь между N участниками — один из них помечается специальным образом, кому идут остатки. Т.е. 100 / 3 == 33 + 33 + 34.

Расскажи об этом бухгалтерам. А то для них дураков придумали банковское округление, и они по тупости трахаются с дебетом-кредитом, даже если все честно проводилось.


M>>Ну, хз. Про фиксированную точку 99% публикаций — о тех случаях, когда точка прибита гвоздями. А оставшийся 1% я не видел

·>Как минимум "во многих СУБД — NUMBER(M,N)"? Разве не оно? Или я не понял что значит прибитость гвоздями в твоём понимании.

Прибитость — это когда ты в компайл-тайме говоришь, где целая, где дробная часть


M>>·>так и десятичные (java.lang.BigDecimal или аналог какой-нибудь). А в int64 или byte[] — это уже детали реализации. int64 просто ограничивает тем, что ты не можешь хранить больше, чем 18 десятичных знаков.

M>>Ну вот я просто и запилил аналог java.lang.BigDecimal. Ни в плюсах, ни в кути — почему-то нет. Хотя вроде Qt умеет в базы данных, а во многих СУБД — NUMBER(M,N) — вполне родной формат. Почему до сих пор не сделали — я хз. Вот я это и исправил, как минимум, для себя.
·>https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software

Ни в стандарте C++, ни в Qt — ничего такого нет. Я запилил своё. У тебя есть какие-то возражения?
Маньяк Робокряк колесит по городу
Re[13]: Точность double
От: · Великобритания  
Дата: 03.06.21 21:56
Оценка:
Здравствуйте, Marty, Вы писали:

M> M>>А у меня можно и 3.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042 и ничего не потеряется.


M> ·>Нигде ничего "не теряется", а отбрасывается. Оно у тебя теряется если ты не понимаешь как оно работает и для чего.

M> У меня ничего не теряется и не "отбрасывается". Умножь 123456789012345678901234567890.12345678901234567890 на 0.000000000000000000000000000000000000000000000000000000000000001
Это абстрактные цифры. Без бизнес-требований. Поэтому смысла не имеет.

M> Я могу получить точный результат, а ты — нет.

А толку от этого результата?

M> M>>Масштаб одной из проблем, согласись, несколько уменьшился, не?

M> ·>Не.
M> Вай?
Потому что появляются другие проблемы, которые не проще, а даже сложнее. Т.к. отбрасывать надо в любом случае.

M> ·>Целочисленное деление по определению работает без потерь знаков — их там нет, терять нечего.

M> ·>Например, в налоговой декларации делишь между N участниками — один из них помечается специальным образом, кому идут остатки. Т.е. 100 / 3 == 33 + 33 + 34.
M> Расскажи об этом бухгалтерам. А то для них дураков придумали банковское округление, и они по тупости трахаются с дебетом-кредитом, даже если все честно проводилось.
Ну хорошие бухгалтеры это и так знают. А плохим да, приходится рассказывать.

M> ·>Как минимум "во многих СУБД — NUMBER(M,N)"? Разве не оно? Или я не понял что значит прибитость гвоздями в твоём понимании.

M> Прибитость — это когда ты в компайл-тайме говоришь, где целая, где дробная часть
Ну в субд значит нет прибитости. Хотя по сути на практике компайл-тайма часто хватает, т.к. нередко бизнес устраивает, скажем 8 точек после запятой и никого нанодоллары не интересуют.

M> ·>https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software

M> Ни в стандарте C++, ни в Qt — ничего такого нет.
В boost вроде как есть, почти стандарт.

M> Я запилил своё. У тебя есть какие-то возражения?

Нет.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[14]: Точность double
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.06.21 22:28
Оценка:
Здравствуйте, ·, Вы писали:

M>> M>>А у меня можно и 3.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042 и ничего не потеряется.


M>> ·>Нигде ничего "не теряется", а отбрасывается. Оно у тебя теряется если ты не понимаешь как оно работает и для чего.

M>> У меня ничего не теряется и не "отбрасывается". Умножь 123456789012345678901234567890.12345678901234567890 на 0.000000000000000000000000000000000000000000000000000000000000001
·>Это абстрактные цифры. Без бизнес-требований. Поэтому смысла не имеет.

Так и претензии твои тоже без "бизнес-требований"

И?


M>> M>>Масштаб одной из проблем, согласись, несколько уменьшился, не?

M>> ·>Не.
M>> Вай?
·>Потому что появляются другие проблемы, которые не проще, а даже сложнее. Т.к. отбрасывать надо в любом случае.

Было бы интересно узнать об этих проблемах


M>> Расскажи об этом бухгалтерам. А то для них дураков придумали банковское округление, и они по тупости трахаются с дебетом-кредитом, даже если все честно проводилось.

·>Ну хорошие бухгалтеры это и так знают. А плохим да, приходится рассказывать.

То есть существование проблемы ты не отриаешь? Ну, уже хорошо


M>> ·>Как минимум "во многих СУБД — NUMBER(M,N)"? Разве не оно? Или я не понял что значит прибитость гвоздями в твоём понимании.

M>> Прибитость — это когда ты в компайл-тайме говоришь, где целая, где дробная часть
·>Ну в субд значит нет прибитости. Хотя по сути на практике компайл-тайма часто хватает, т.к. нередко бизнес устраивает, скажем 8 точек после запятой и никого нанодоллары не интересуют.

Есть прибитость в рантайм. А про нанодоллары ты расскажи тут —
Автор: Real 3L0
Дата: 02.06.21



M>> ·>https://en.wikipedia.org/wiki/List_of_arbitrary-precision_arithmetic_software

M>> Ни в стандарте C++, ни в Qt — ничего такого нет.
·>В boost вроде как есть, почти стандарт.

M>> Я запилил своё. У тебя есть какие-то возражения?

·>Нет.

Вот и договорились
Маньяк Робокряк колесит по городу
Re[15]: Точность double
От: Vzhyk2  
Дата: 04.06.21 03:37
Оценка:
Здравствуйте, Marty, Вы писали:

M>Без теории, так-то, особого смысла считать нет — хрень насчитаешь, обязательно что-нибудь либо сойдётся не там, где должно, либо разойдётся там, где не должно, и пр

Были два понятия, сходимость и устойчивость и на них мы действительно много времени тратили.
Но я учился в конце совка и выпускники ФПМ тогда всей толпой в военку работать шли (отсюда у нас и стипендия повышенная была и государство серьезно к прикладной математике относилось).
В военке в те времена нужно было много чего считать и правильно.
Программирование же у нас было хоть и приличное, но оно шло вторым планом относительно собственно прикладной математики.
Ну а без пониманиря особенностей вычислений на компьтерах в численный методах никак.
Re[13]: Точность double
От: pagid Россия  
Дата: 04.06.21 05:15
Оценка:
Здравствуйте, Marty, Вы писали:

M>У меня ничего не теряется и не "отбрасывается". Умножь 123456789012345678901234567890.12345678901234567890 на 0.000000000000000000000000000000000000000000000000000000000000001

M>Я могу получить точный результат, а ты — нет.
Зачем он тебе и что с ним делать?

M>Расскажи об этом бухгалтерам. А то для них дураков придумали банковское округление, и они по тупости трахаются с дебетом-кредитом, даже если все честно проводилось.

Да не нужно в жизни банковское округление. Тем более тем, кто трахаются с дебетом-кредитом. В статистике, да это один из способов уменьшения погрешности, не самый лучший.

Те кто "трахаются с дебетом-кредитом" работают всегда с целыми копейками (ну может с сотыми долями цента, иногда на американский манер если). И никакое "банковское" округление им не нужно. А то, что оно по умолчанию у американцев, так это такой их таракан, наподобие кантри-музыки и пива пинтами.
Re[15]: Точность double
От: · Великобритания  
Дата: 04.06.21 07:57
Оценка:
Здравствуйте, Marty, Вы писали:

M>>> У меня ничего не теряется и не "отбрасывается". Умножь 123456789012345678901234567890.12345678901234567890 на 0.000000000000000000000000000000000000000000000000000000000000001

M>·>Это абстрактные цифры. Без бизнес-требований. Поэтому смысла не имеет.
M>Так и претензии твои тоже без "бизнес-требований"
M>И?
Мои претензии как раз в том, что ты не озвучил никаких бизнес-требований и вдруг заявляешь "ничего не потеряется", как будто это какое-то вечное благо и так и надо делать. Это, как раз, бОльшая проблема. За исключением каких-то редких академических задач, 100500 знаков после запятой никому не нужны.

M>>> ·>Не.

M>>> Вай?
M>·>Потому что появляются другие проблемы, которые не проще, а даже сложнее. Т.к. отбрасывать надо в любом случае.
M>Было бы интересно узнать об этих проблемах
Нет такой проблемы, чтобы ничего не терялось. Проблема как раз в том, чтобы решить когда и как и что отбрасывать.

M>>> Прибитость — это когда ты в компайл-тайме говоришь, где целая, где дробная часть

M>·>Ну в субд значит нет прибитости. Хотя по сути на практике компайл-тайма часто хватает, т.к. нередко бизнес устраивает, скажем 8 точек после запятой и никого нанодоллары не интересуют.
M>Есть прибитость в рантайм. А про нанодоллары ты расскажи тут —
Автор: Real 3L0
Дата: 02.06.21

Типичная бухгалтерия в пользу банка... ичсх, нанодоллары таки не нужны.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: Точность double
От: Michael7 Россия  
Дата: 06.06.21 11:37
Оценка:
Здравствуйте, Vzhyk2, Вы писали:

H>>Забудь про «==« для плавающей точки. Только разницу с эпсилон сравнивай

V>Чушь. Всё зависит от того, что именно ты хочешь сделать и где.

В общем случае да, на практике использование == для плавучки — это или из-за незнания как правильно работать с машинной арифметикой или какой-то трюк, хак в конкретном месте.
Re[5]: Точность double
От: Michael7 Россия  
Дата: 06.06.21 11:49
Оценка:
Здравствуйте, Kazmerchuk Pavel, Вы писали:


KP>Решение уже привели. Задача шагать по сеточной функции, точно попадая в узлы. Узлы подвижны.


Тогда лучше узлы нумеровать целочисленными значениями и шагать инкрементами, а координаты вычислять.
Re[6]: Точность double
От: Kazmerchuk Pavel  
Дата: 06.06.21 16:49
Оценка:
Здравствуйте, Michael7, Вы писали:

M>Здравствуйте, Kazmerchuk Pavel, Вы писали:



KP>>Решение уже привели. Задача шагать по сеточной функции, точно попадая в узлы. Узлы подвижны.


M>Тогда лучше узлы нумеровать целочисленными значениями и шагать инкрементами, а координаты вычислять.

Что значит шагать инкрементами? Шаги и между узлами попадают.
Re[7]: Точность double
От: Michael7 Россия  
Дата: 06.06.21 17:02
Оценка:
Здравствуйте, Kazmerchuk Pavel, Вы писали:


M>>Тогда лучше узлы нумеровать целочисленными значениями и шагать инкрементами, а координаты вычислять.

KP>Что значит шагать инкрементами? Шаги и между узлами попадают.

Если у тебя сетка какая-то, то есть ее топология в виде узлов. Вот и предусмотреть нумерацию исключительно индексами i,j,k — как-то так. Может быть с дополнительным параметром отступа от узла или что-то в этом роде. Если же нужно именно проверять куда попал какой-то шаг, то все же сравнивать надо не == а с погрешностью. abs(a-b)<epsilon
Re[7]: Точность double
От: pagid Россия  
Дата: 06.06.21 17:58
Оценка:
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>Что значит шагать инкрементами? Шаги и между узлами попадают.

Количество узлов фиксированное для одной модели?
Re[8]: Точность double
От: Kazmerchuk Pavel  
Дата: 07.06.21 17:41
Оценка:
Здравствуйте, Michael7, Вы писали:

M>Здравствуйте, Kazmerchuk Pavel, Вы писали:



M>>>Тогда лучше узлы нумеровать целочисленными значениями и шагать инкрементами, а координаты вычислять.

KP>>Что значит шагать инкрементами? Шаги и между узлами попадают.

M>Если у тебя сетка какая-то, то есть ее топология в виде узлов. Вот и предусмотреть нумерацию исключительно индексами i,j,k — как-то так. Может быть с дополнительным параметром отступа от узла или что-то в этом роде. Если же нужно именно проверять куда попал какой-то шаг, то все же сравнивать надо не == а с погрешностью. abs(a-b)<epsilon


Есть функция (сеточная), заданная значениями в некоторых точках (узлах). Количество и расположение узлов произвольное. Есть система дифференциальных уравнений (ДУ), которая интегрируется численным методом. Правые части системы ДУ зависят от сеточной функции. Численный метод получает на вход в том числе шаг (по времени). Длинна шага каждый раз вычисляется исходя и требуемой точности интегрирования. Проблема в том, что сеточная функция имеет разрывы в узлах. Если метод интегрирования не попадает в точки разрыва, он теряет точность. Я вычисляю шаг до следующего узла (как написали выше) и ошибку. Если ошибка нулевая — попадем точно в узел, всё ОК, если нет, корректирую шаг чтобы гарантировано не "перепрыгнуть" узел.
Re[9]: Точность double
От: Michael7 Россия  
Дата: 07.06.21 20:18
Оценка: +1
Здравствуйте, Kazmerchuk Pavel, Вы писали:

KP>Есть функция (сеточная), заданная значениями в некоторых точках (узлах). Количество и расположение узлов произвольное. Есть система дифференциальных уравнений (ДУ), которая интегрируется численным методом. Правые части системы ДУ зависят от сеточной функции. Численный метод получает на вход в том числе шаг (по времени). Длинна шага каждый раз вычисляется исходя и требуемой точности интегрирования. Проблема в том, что сеточная функция имеет разрывы в узлах. Если метод интегрирования не попадает в точки разрыва, он теряет точность. Я вычисляю шаг до следующего узла (как написали выше) и ошибку. Если ошибка нулевая — попадем точно в узел, всё ОК, если нет, корректирую шаг чтобы гарантировано не "перепрыгнуть" узел.


Чего-то не доходит. Если шаг должен попадать в узлы, то его не надо корректировать, его надо сразу дискретным делать так, чтобы соответствовал узлам.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.