Конференция "Прочее" » double для десятичной системы счисления
 
  • KSergey © (27.02.19 10:15) [0]
    Все мы любим double со всеми его приколами для операций с [дробными] числами. (извините, я не сумел выбрать верный термин, поэтому написал так)
    Когда мы пытаемся натянуть их использование на повсеместно используемые значения, представленные десятичными дробями, но получает массу весёлостей. При этом в 99% реальных случаев на самом деле входными значениями являются значения, заданные десятичной дробью, и выходные значения тоже хотим получить в виде десятичной дроби.

    Собственно основная проблема double в том, что там - степени двойки, а не степени десяти хранятся.

    Вопроса у меня два в связи с этим:

    1) Подскажите, по каким словам загуглить готовые реализации double, который бы однозначно отображался именно на десятичное представление. Я не сумел придумать.

    2) Почему мы до сих пор живём с тем double, который имеем? когда-то понятно его сделали для облегчения реализации в ЭВМ. Но сейчас, казалось бы, уже не должно быть проблемой сделать аппаратную реализацию работы с любым double. Но почему этого нет? и не видно даже каких-то подвижек? либо я плохо смотрю

    ЗЫ
    99% - субъективная цифра, у меня нет пруфов
  • dmk © (27.02.19 10:32) [1]
    >загуглить готовые реализации double
    С Double как раз нет никаких проблем. Есть проблемы с Single, да и то решаемые, а вот что не так с Double? Точность у Double даже с запасом (15 знаков в десятичной системе).

    function DoubleEpsilon: Double;
    begin
     R := 1.0;
     while (1.0 + R / 2.0) > 1.0 do R := (R / 2.0);
     Result := R; //0.000000000000000222044604925031 //15 знаков КАРЛ! 15!!!!
    end;
  • dmk © (27.02.19 10:40) [2]
    Да и никто, заметьте, никто не мешает вам спроектировать процессор с байтом в 10-бит :)
    А также разработать систему команд на основе вашего нового байта. Все внимательно ждут и верят в Вас.
  • Styx © (27.02.19 11:04) [3]
    Для большинства задач привязка к десятичной системе не нужна. Нужна в финансовых расчётах, для этого есть тип Decimal. Если его возможностей не хватает, придётся, видимо, придумывать что-то своё.
  • KSergey © (27.02.19 11:06) [4]
    > dmk ©   (27.02.19 10:32) [1]
    > С Double как раз нет никаких проблем. Есть проблемы с Single,
    >  да и то решаемые, а вот что не так с Double? Точность у
    > Double даже с запасом (15 знаков в десятичной системе).

    Это так только кажется.
    Уже суммы денег вполне себе близки к 15 тем самым разрядам имеют место быть на счетах банковских (особенно если хотят 4 или 6 знаков после запятой видеть), так что это только кажется, что увеличение точности что-то решает. На самом деле - совершенно ничего не решает, лишь позволяет до поры до времени закрыть глаза на проблему. Но не решает вообще ничего.
  • Styx © (27.02.19 11:08) [5]
    И проблема не в использовании степеней двойки в компьютере, а в использовании степеней десятки в быту. Именно десятка приводит к ряду чудес, которых бы не было при использовании двойки. Поэтому использовать не-двоичное представление где-то, кроме вывода на экран, едва ли оправданно.
  • dmk © (27.02.19 11:09) [6]
    >KSergey ©   (27.02.19 11:06) [4]
    Пишите модуль вычислений с длинной математикой. Алгоритмы достаточно простые.
    Сделайте для начала 128 бит (+, -, /, *), а там может и этого хватит пока.
  • Тимохов Дима © (27.02.19 11:09) [7]

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


    типа decimal в дельфи нет.
    он до сих пор не реализован (в quality central лежит соотв. тикет уже лет 20):

    Наскок знаю в современных версиях дельфи все осталось так же:

    > System.pas:
    > //varDecimal  = $000E; { vt_decimal     14 } {UNSUPPORTED
    > as of v6.x code base}


    я работаю с decimal, но сам его импортирую из oleaut32.dll типа того:

    > function _VarDecAdd(var aDec1: ActiveX.TDecimal; var
    > aDec2: ActiveX.TDecimal;
    >       out aDecResult: ActiveX.TDecimal): HResult;
    >       stdcall; external 'oleaut32.dll' name 'VarDecAdd';
  • KSergey © (27.02.19 11:09) [8]
    Когда мы работаем с физ. величинами и физ. расчетами - то там да, там в самом деле плавающие точки - отличная вещь.
    А вот когда у меня есть 1 рубль, но при этом я смогу купить только 99 колобков спичек по 1 примерно копейке, после чего деньги закончатся - то ту-то только и начнёшь понимать всю глубину проблемы.
  • Styx © (27.02.19 11:10) [9]
    А деньги не надо считать с плавающей запятой. Они же дискретны, их надо считать целыми числами. И большинство программ так и делают.
  • Тимохов Дима © (27.02.19 11:12) [10]

    > Styx ©   (27.02.19 11:10) [9]
    > А деньги не надо считать с плавающей запятой. Они же дискретны,
    >  их надо считать целыми числами. И большинство программ
    > так и делают.


    +1

    Если хватает размерности, то можно currency использовать.
  • Styx © (27.02.19 11:13) [11]

    > типа decimal в дельфи нет.

    Sorry, в Delphi он Currency.
  • Тимохов Дима © (27.02.19 11:14) [12]

    > Styx ©   (27.02.19 11:13) [11]
    > > типа decimal в дельфи нет.
    > Sorry, в Delphi он Currency.


    ну мне маловат currency оказался.
    из-за малого колва знаков после запятой.
    поэтому decimal взял.
  • KSergey © (27.02.19 11:15) [13]
    > Styx ©   (27.02.19 11:04) [3]
    >  Нужна в финансовых расчётах, для этого есть тип Decimal.

    Decimal - это фиксированная точка. И тут уже нужно очень следить за руками, ибо в промежуточных расчетах легко потерять вообще всё.

    Я от того и спросил про аналог Double, т.е. тип с плавающей точкой, то однозначно отображаемый на десятичную систему счисления.
    Ну не может же быть, что такое никому не требовалось?
  • dmk © (27.02.19 11:18) [14]
    В процессоре всего 3 вещественных типа. Остальное производные или своя мат-библиотека.
  • Тимохов Дима © (27.02.19 11:28) [15]

    > Decimal - это фиксированная точка. И тут уже нужно очень
    > следить за руками, ибо в промежуточных расчетах легко потерять
    > вообще всё.

    там 18 знаков перед запятой, и 10 знаков после запятой.
    это до фига, даже для расчетов.
    ну да, надо помнить что лучше сначала умножить, потом поделить.
    точности хватает даже для учета себестоимости товаров.
  • RWolf © (27.02.19 11:35) [16]
  • Styx © (27.02.19 11:50) [17]
  • KSergey © (27.02.19 12:21) [18]
    спасибо за ссылки!
  • иосифович © (27.02.19 12:23) [19]
    А вот когда у меня есть 1 рубль, но при этом я смогу купить только 99 колобков спичек по 1 примерно копейке, после чего деньги закончатся - то ту-то только и начнёшь понимать всю глубину проблемы.



    глубина мелкая.

    внутренние расчеты делаются с точностью дабл.
    наружу выдаются результаты с дискретностью денежной единицы (чтобы в кассе могли заплатить или сдать сдачу)
    дельту не откусывают, а учитывают в следующих периодах.
  • Mystic © (27.02.19 13:23) [20]
    (1) Fixed point, decimal, currency
    (2) Просто то, что ты хочешь, любой программист может легко реализовать на основании целочисленного типа, например, храним сумму не в долларах, а в центах и т. п. В принципе, готовых реализаций over 9000+ Для научных численных вычислений фиксированная точка абсолютно не годиться, потому что часто будем выходить за пределы её точности, например, если брать градиентный спуск, то шаг может быть очень маленьким, например 1e-6, а значение целевой функции очень большим 1e+6. А вся точность десятичного представления разбивается о квадратные корни, логарифмы, экспоненты и т. п.

    Хотя фон Нейман в своё время утверждал, что программистам достаточно фиксированной точки, а уже любой вменяемый программист легко сможет на её основе реализовать представление в виде мантиссу/экспоненты наиболее эффективное для данного алгоритма. Ну и если брать классику типа Уилкинсон Дж.Х., Райнш С. Справочник алгоритмов на языке Алгол. Линейная алгебра, то там часто можно встретить в коде как раз ручную работу с мантиссой/экспонентой.
  • KSergey © (27.02.19 13:26) [21]
    Fixed point не то.
    Хочется плавающую точку.
  • иосифович © (27.02.19 13:27) [22]
    храним сумму не в долларах, а в центах

    но тут внезапно появляются проценты.
  • Mystic © (27.02.19 13:52) [23]

    > Хочется плавающую точку.


    Зачем? Как только происходит потеря точности, сразу становится неважным, как у тебя представлены числа. А в финансовых приложениях вряд-ли будет большо́й диапазон значений, 64 бита даст тебе примерно 18 порядков, для доллара получаем триллион это 1e+12, следовательно у нас ещё будет 6 знаков после точки. Также нет проблем в использовании 128 бит (ещё 18 порядков).

    Если брать Ethereum VM, там все суммы представлены 256-битными числами, 1 ETH это 1e+18 wei (минимальная единица). Такой точности всем более чем достаточно.
  • ВладОшин © (27.02.19 17:38) [24]
    Хочешь повторить тот случай, когда работник банка подсунул софтинку которая все эти хвостики переводила на его счет ? )
  • virex(home) © (27.02.19 18:57) [25]
    > KSergey ©   (27.02.19 13:26) [21]
    >
    > Fixed point не то.
    > Хочется плавающую точку.
    см. аналог BigDecimal в java

    хоть сто тыщь после запятой
  • KSergey © (28.02.19 09:09) [26]
    > ВладОшин ©   (27.02.19 17:38) [24]
    > Хочешь повторить тот случай, когда работник банка подсунул
    > софтинку которая все эти хвостики переводила на его счет ? )

    Это-то как раз просто, вытекает из самой природы всей этой проблемы, и это как раз так у меня и работает.
    А вот как сделать, чтобы не переводила - вот над чем бьюсь. И чета без особого успеха.
  • dmk © (28.02.19 14:46) [27]
    >А вот как сделать, чтобы не переводила - вот над чем бьюсь. И чета без особого успеха.
    Я округлял одну часть значения в нужную сторону, а вторую получал вычитанием от округленного. Вполне рабочий вариант. За 10 лет налоговая ничего не вернула на пересчет.
  • han_malign © (28.02.19 17:51) [28]

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

    https://habr.com/ru/post/423469/
  • Inovet © (01.03.19 05:18) [29]
    > [5] Styx ©   (27.02.19 11:08)
    > И проблема не в использовании степеней двойки в компьютере,
    > а в использовании степеней десятки в быту.

    Это точно подмечено - бэд дизайн. Правильно надо было сделать по 1 пальцу на каждой руке, как компромисное решение можно было сделать по 4 или даже по 8 тоже неплохо. Но решения с двумя руками всё-таки не универсальны, например, они неудобны в архитектуре DEC процессоров, где надо на одну руку делать 4 пальца а на другую 3, что усложняет модель и добавляет лишние сущности и ассиметрию. Самое универсальное решение 1 рука, тогда пространство вариаций с количеством пальцев раширяются от 1 и до неких разумных величин, поределяемых типовими архитектурами процессоров.
  • Styx © (01.03.19 09:42) [30]
    :)
    Я имел в виду что-то типа этого:
    https://ru.wikipedia.org/wiki/Закон_Бенфорда
  • Inovet © (01.03.19 17:02) [31]
    > [30] Styx ©   (01.03.19 09:42)
    > Я имел в виду что-то типа этого:
    > https://ru.wikipedia.org/wiki/Закон_Бенфорда

    НуТыПонял.
  • Inovet © (01.03.19 17:04) [32]
    > [31] Inovet ©   (01.03.19 17:02)

    Да. смайл подразумевался.:)
 
Конференция "Прочее" » double для десятичной системы счисления
Есть новые Нет новых   [134427   +34][b:0][p:0.002]