Re[11]: 64 бита для целого без вариантов - добро или зло?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 28.07.23 19:07
Оценка:
Здравствуйте, netch80, Вы писали:

M>>А есть варианты сделать long decimal более оптимально, и при этом без особых извращений?


N>Загляни в исходники .NET Core.

N>Там работают группами по 9 цифр на 32-битное хранилище.
N>Промежуточные операции 64-битные.
N>Но насколько это "особые извращения", не знаю — код действительно сложнее.


Накидал тест для своего Decimal, вычисление числа Пи по формуле Валлиса:
  Скрытый текст
/*! \file
    \brief Тест производительности доморощеного Decimal на вычислении числа Пи

 */

#include <iostream>
#include <exception>
#include <stdexcept>
#include <sstream>
#include <iomanip>

#define MARTY_NO_QT

#include "safe_main.h"
#include "../../marty_decimal.h"
#include "../../undef_min_max.h"


// Можно попробовать использовать ряд обратных квадратов - https://ru.wikipedia.org/wiki/%D0%A0%D1%8F%D0%B4_%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D1%85_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BE%D0%B2
// == Pi**2 / 6   - сумма 1/N**2 - деление и возведение в степень

// Формула Валлиса - https://ru.wikipedia.org/wiki/%D0%A4%D0%BE%D1%80%D0%BC%D1%83%D0%BB%D0%B0_%D0%92%D0%B0%D0%BB%D0%BB%D0%B8%D1%81%D0%B0
// Только деление и умножение

//----------------------------------------------------------------------------
inline
std::uint32_t getMillisecTick()
{
    return marty::for_decimal_tests::getMillisecTick();
}

//----------------------------------------------------------------------------
void doTest(int divPrecision, unsigned numIterations)
{
    std::uint32_t startTick = getMillisecTick();

    marty::Decimal::setDivisionPrecision(divPrecision); // максимальное число знаков при делении

    marty::Decimal res = 1;
    for(unsigned i=1; i!=numIterations; ++i)
    {
        // Формула Валлиса

        // i = 1   2   3   4   5   6   7   8    9   10
        //
        //     2   2   4   4   6   6   8   8   10   10
        //     - * - * - * - * - * - * - * - * -- * -- * ...
        //     1   3   3   5   5   7   7   9    9   11

        if (i&1)
        {
            res *= marty::Decimal(i+1) / marty::Decimal(i);
        }
        else
        {
            res *= marty::Decimal(i)   / marty::Decimal(i+1);
        }

        #if defined(DEBUG) || defined(_DEBUG)

            std::cout << i << ": " << res << "\n";

        #endif
        
    }

    std::uint32_t endTick = getMillisecTick();

    auto pi = res * 2;
    
    std::cout << "Prec: " << divPrecision << "\n";
    std::cout << "N   : " << numIterations << "\n";
    std::cout << "T el: " << (endTick-startTick) << "\n";
    std::cout << "pi  : " << pi  << "\n";
    std::cout << "\n";

}




MARTY_DECIMAL_MAIN()
{
    doTest( 50,  1000);
    doTest( 50,  2000);
    doTest( 50,  3000);
    doTest( 50,  4000);
    doTest( 50,  5000);
    doTest( 50,  6000);
    doTest( 50,  7000);
    doTest( 50,  8000);
    doTest( 50,  9000);
    doTest( 50, 10000);
    doTest( 50, 11000);
    doTest( 50, 12000);
    doTest( 50, 13000);
    doTest( 50, 14000);
    doTest( 50, 15000);

    doTest(100,  1000);
    doTest(100,  2000);
    doTest(100,  3000);
    doTest(100,  4000);
    doTest(100,  5000);

    doTest(200,  1000);
    doTest(200,  2000);
    doTest(200,  3000);
    doTest(200,  4000);
    doTest(200,  5000);


    return 0;

}


Там конечный результат не важен, просто взял первый попавшийся простой алгоритм с умножениями и делениями (ну и ещё конвертация из int).

Если есть специалисты по дот нету, было бы интересно аналогичный тест на нём посмотреть, сравнить с моей реализацией.

Я сам конечно могу что-то написать, но, не зная платформы и языка, могу сделать кривой неоптимальный код
Маньяк Робокряк колесит по городу
Re: 64 бита для целого без вариантов - добро или зло?
От: Константин Б. Россия  
Дата: 31.07.23 18:18
Оценка: :)
Здравствуйте, Shmj, Вы писали:

S>Вот новые ЯП типа Dart — решили что нехрен делать 100500 разных вариантов целых чисел (со знаком/без знака, 8, 16, 32, 64) — а просто для всего сделать 64 бита со знаком: https://dart.dev/language/built-in-types


S>Умно?


Тут в соседнем топике
Автор: Евгений Музыченко
Дата: 05.05.20
на протяжении уже 400 сообщений на серъезных щах спорят нужно ли использовать знаковые целые или беззнаковые.
Один целый тип — это не просто умно. Это гениально.
Re[2]: 64 бита для целого без вариантов - добро или зло?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.08.23 05:41
Оценка:
Здравствуйте, Константин Б., Вы писали:

КБ>Тут в соседнем топике
Автор: Евгений Музыченко
Дата: 05.05.20
на протяжении уже 400 сообщений на серъезных щах спорят нужно ли использовать знаковые целые или беззнаковые.

КБ>Один целый тип — это не просто умно. Это гениально.

Какого размера должен быть этот тип, чтобы гениально закрыть все проблемы?
The God is real, unless declared integer.
Re[3]: 64 бита для целого без вариантов - добро или зло?
От: CreatorCray  
Дата: 02.08.23 09:44
Оценка: +1
Здравствуйте, netch80, Вы писали:

N>Какого размера должен быть этот тип, чтобы гениально закрыть все проблемы?

Безразмерного, видимо
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: 64 бита для целого без вариантов - добро или зло?
От: Константин Б. Россия  
Дата: 03.08.23 05:20
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, Константин Б., Вы писали:


КБ>>Тут в соседнем топике
Автор: Евгений Музыченко
Дата: 05.05.20
на протяжении уже 400 сообщений на серъезных щах спорят нужно ли использовать знаковые целые или беззнаковые.

КБ>>Один целый тип — это не просто умно. Это гениально.

N>Какого размера должен быть этот тип, чтобы гениально закрыть все проблемы?


Неограниченного конечно.
Re[4]: 64 бита для целого без вариантов - добро или зло?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.08.23 05:34
Оценка: +1
Здравствуйте, Константин Б., Вы писали:

N>>Здравствуйте, Константин Б., Вы писали:


КБ>>>Тут в соседнем топике
Автор: Евгений Музыченко
Дата: 05.05.20
на протяжении уже 400 сообщений на серъезных щах спорят нужно ли использовать знаковые целые или беззнаковые.

КБ>>>Один целый тип — это не просто умно. Это гениально.

N>>Какого размера должен быть этот тип, чтобы гениально закрыть все проблемы?


КБ>Неограниченного конечно.


А в Dart, с которого началось обсуждение, он 64-битный. Непорядок-с.
The God is real, unless declared integer.
Re[2]: 64 бита для целого без вариантов - добро или зло?
От: Sharowarsheg  
Дата: 03.08.23 21:14
Оценка:
Здравствуйте, ononim, Вы писали:

S>>Что скажете?

O>LEB128 тогда уже. Чтоб наверняка.

Это пока кто-нибудь SHA не захочет в него засунуть.
Re[2]: 64 бита для целого без вариантов - добро или зло?
От: flаt  
Дата: 04.08.23 04:21
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Смотря для какого языка. Так делать нельзя, если:

N>- язык должен иметь возможность получать доступ к железу
N>- язык предполагает парсинг и сериализацию бинарных данных/файлов/протоколов.

https://api.dart.dev/stable/3.0.5/dart-ffi/dart-ffi-library.html
Re[11]: 64 бита для целого без вариантов - добро или зло?
От: s_aa Россия  
Дата: 04.08.23 04:33
Оценка:
N>Бухучёт банка в это не лез, и не знаю, имеет ли он отношение к этому.

Насколько помню со времени банковской работы, при конвертации валют погрешности округления идут либо на спецсчет доходов или расходов банка. И так и так бывает, как получится.
Жизнь не обязана доставлять удовольствие. Достаточно отсутствия страданий.
Re[11]: 64 бита для целого без вариантов - добро или зло?
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.08.23 06:37
Оценка:
Здравствуйте, netch80, Вы писали:

N>На самом деле тут вообще ещё вопрос, при чём тут тьюринг-полнота языка на фазе трансляции, когда проверки всё равно надо впихивать в рантайм. Но если мы не сойдёмся по сказанному выше, то этот вопрос поднимать смысла нет.

Тут интереснее возможность не впихивать в рантайм избыточные проверки.
Например, при присванивании из RangeInteger<10, 20> в RangeInteger<5, 30> никакие проверки делать не надо.
В простых случаях вида RangeInteger<10, 50> a = 42; компилятору легко — после разворачивания шаблона сравнения if(42<10) будут выброшены.
А вот как отследить инварианты через границу двух разных типов?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: 64 бита для целого без вариантов - добро или зло?
От: ononim  
Дата: 04.08.23 07:51
Оценка: 2 (1)
S>>>Что скажете?
O>>LEB128 тогда уже. Чтоб наверняка.
S>Это пока кто-нибудь SHA не захочет в него засунуть.
128 в LEB128 это не о том, что числа в нем 128 битные, а о том, что бит 128 в октете означает 'продолжение' числа на дополнительный октет. Фактическая битность не ограничена.
Как много веселых ребят, и все делают велосипед...
Re[2]: 64 бита для целого без вариантов - добро или зло?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.08.23 08:51
Оценка:
Здравствуйте, ononim, Вы писали:

S>>Что скажете?

O>LEB128 тогда уже. Чтоб наверняка.

Ну форматов передачи целого переменного размера дофига, и это не единственный.
И точно не оптимальный для внутреннего представления — он нацелен на сериализацию.
И не лучший, вообще-то. Почему в DWARF впихнули именно LE — непонятно.
Он легче пишется, но сложнее читается, а при том, что время отладчика на чтение этих значений заметно дороже времени линкера на их запись — выглядит нелепым решением.
The God is real, unless declared integer.
Re[12]: 64 бита для целого без вариантов - добро или зло?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.08.23 09:04
Оценка: 2 (1)
Здравствуйте, Sinclair, Вы писали:

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


N>>На самом деле тут вообще ещё вопрос, при чём тут тьюринг-полнота языка на фазе трансляции, когда проверки всё равно надо впихивать в рантайм. Но если мы не сойдёмся по сказанному выше, то этот вопрос поднимать смысла нет.

S>Тут интереснее возможность не впихивать в рантайм избыточные проверки.
S>Например, при присванивании из RangeInteger<10, 20> в RangeInteger<5, 30> никакие проверки делать не надо.
S>В простых случаях вида RangeInteger<10, 50> a = 42; компилятору легко — после разворачивания шаблона сравнения if(42<10) будут выброшены.
S>А вот как отследить инварианты через границу двух разных типов?

Это как раз уже делается на существующих на данный момент средствах.
Clang имеет __builtin_assume(), который как раз говорит "считай данное условие гарантированным со стороны кодера". GCC (и Clang для совместимости) имеет __builtin_unreachable(), через который assume делается так:

#define assume(x) {if(!x) __builtin_unreachable(); }

И оптимизатор тоже умеет отбрасывать лишние проверки на таком основании.

Для такого RangeInteger мы можем написать
template <int Min, int Max> class RangeInteger {
  ...
  operator underlying_int_t() const {
    if (mValue < Min) {__builtin_unreachable();} // или __builtin_assume(mValue >= Min);
    if (mValue > Max) {__builtin_unreachable();} // или __builtin_assume(mValue >= Max);
    return mValue;
  }
};


Главное не забыть делать реальные проверки при присвоении (в конструкторе, operator=, где ещё надо — ты в курсе).

В твоём примере типа
RangeInteger<10, 20> i1;
...
RangeInteger<5, 30> i2 = i1;


компилятор получит гарантии 10 <= i1.mValue <= 20, и выкинет лишние проверки при присвоении i2.

Переносилось ли это в какие-то другие компиляторы (хоть в MSVC) — я не узнавал.
The God is real, unless declared integer.
Отредактировано 04.08.2023 11:31 netch80 . Предыдущая версия . Еще …
Отредактировано 04.08.2023 9:06 netch80 . Предыдущая версия .
Re[12]: 64 бита для целого без вариантов - добро или зло?
От: pagid_ Россия  
Дата: 04.08.23 11:25
Оценка:
Здравствуйте, s_aa, Вы писали:

_>Насколько помню со времени банковской работы, при конвертации валют погрешности округления идут либо на спецсчет доходов или расходов банка. И так и так бывает, как получится.

Откуда там погрешности округления? Если на счетах все валюты будут с точностью до копеек, центов, а не их долей. В доходы/расходы идут курсовые разницы.
Re[13]: 64 бита для целого без вариантов - добро или зло?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.08.23 11:29
Оценка: :)
Здравствуйте, pagid_, Вы писали:

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


_>>Насколько помню со времени банковской работы, при конвертации валют погрешности округления идут либо на спецсчет доходов или расходов банка. И так и так бывает, как получится.

_>Откуда там погрешности округления? Если на счетах все валюты будут с точностью до копеек, центов, а не их долей. В доходы/расходы идут курсовые разницы.

Вот я сейчас глянул курс — 36.5686.
Конверчу 30$ — получаю 1097.058 грн в идеале — но на счёт попадёт или 1097.05, или 1097.06.
The God is real, unless declared integer.
Re[14]: 64 бита для целого без вариантов - добро или зло?
От: pagid_ Россия  
Дата: 04.08.23 12:03
Оценка:
Здравствуйте, netch80, Вы писали:

N>Вот я сейчас глянул курс — 36.5686.

N>Конверчу 30$ — получаю 1097.058 грн в идеале — но на счёт попадёт или 1097.05, или 1097.06.
Вот именно на эту сумму и проводится операция. И в общем-то без разницы 1097.05 или 1097.06. Тут главное чтобы именно на эту сумму увеличился остаток на твоем счете, именно она была показана тебе, как как результат операции и на неё уменьшился какой-то там счет банка. Если будет несоответствие в последнем случае "дебет не сойдется с кредитом" Никакие доли копеек никуда девать не нужно — да и невозможно — остатки на всех счетах учитываются с точностью до копеек.

Курс — не деньги. Его нет в качестве остатка на счете, он не уменьшается и не увеличивается при проведении операции.
Re[15]: 64 бита для целого без вариантов - добро или зло?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.08.23 12:56
Оценка:
Здравствуйте, pagid_, Вы писали:

_>Курс — не деньги. Его нет в качестве остатка на счете, он не уменьшается и не увеличивается при проведении операции.


Это ты так думаешь. А учёт может думать иначе.

Вот пусть банк округлил мне до 1097.06. Пусть прошло 1000 таких покупателей по 30$. В сумме банк выдал продавцам валюты 1097060 грн.
Но в учёт операций должна была пойти продажа 30000$, которые по этому курсу 1097058 грн.
Получается, банк переплатил 2 гривны.

Оно конечно мелочи, но учёт должен сойтись ровно в 0. И вот тут начинается вопрос, а какая из практик бухучёта применяется и что она требует.

То, что сказал s_aa — эти доли копейки и сливаются на спец. счёт доходов и расходов по конвертации, по сумме описанных операций на нём "добавилось" минус две гривны.

Я уже не помню, как зовётся этот подход. Но он есть, как тот суслик
The God is real, unless declared integer.
Re[16]: 64 бита для целого без вариантов - добро или зло?
От: pagid_ Россия  
Дата: 04.08.23 13:26
Оценка: +1
Здравствуйте, netch80, Вы писали:

N>Это ты так думаешь. А учёт может думать иначе.

Так думают закон, а вслед за ним люди занимающиеся учетом и создающие учетные программы.

N>Вот пусть банк округлил мне до 1097.06. Пусть прошло 1000 таких покупателей по 30$. В сумме банк выдал продавцам валюты 1097060 грн.

N>Но в учёт операций должна была пойти продажа 30000$, которые по этому курсу 1097058 грн.
Нет, в учете пройдет 1097060 грн., но никак иначе. Сумма операций это и именно сумма операций, а не одна, по какому-то курсу. Он несколько раз на дню может меняться.
И никому она быть 1097058 не должна.

N>Получается, банк переплатил 2 гривны.

Не получается.

N>Оно конечно мелочи, но учёт должен сойтись ровно в 0. И вот тут начинается вопрос, а какая из практик бухучёта применяется и что она требует.

С общей 30000$ умноженным на курс? Нет, не должен. Никого в учете не интересует сколько будет, если 30000$ умножить на курс. Интересует и является учитываемой величиной сумма валютных операций (переведенных между счетами денег) за период.

N>Я уже не помню, как зовётся этот подход. Но он есть, как тот суслик

В валютных операциях действительно могут быть курсовые разницы попадающие на счет доходов/расходов, а не на какой-то спец. Но они возникают не из-за округления, а из-за того, что курс между моментом заключения договора и фактической операцией (отгрузкой товара, конвертацией валюты по текущему курсу) может измениться.
Re: 64 бита для целого без вариантов - добро или зло?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 04.08.23 14:54
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Что скажете?

Я вот смотрю на эволюцию C# они становятся все ближе к нативу. Span<T>, ref поля и ref scoped,Встроенные массивы,Function Pointers bnl
и солнце б утром не вставало, когда бы не было меня
Re[14]: 64 бита для целого без вариантов - добро или зло?
От: CreatorCray  
Дата: 04.08.23 17:31
Оценка:
Здравствуйте, netch80, Вы писали:

_>>В доходы/расходы идут курсовые разницы.

N>Конверчу 30$ — получаю 1097.058 грн в идеале — но на счёт попадёт или 1097.05, или 1097.06.

Не ну ты явно читать не умеешь
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.