All streams
Search
Write a publication
Pull to refresh
14
0
Сергей Б. @sergey-b

Пользователь

Send message
Я разделяю отношение автора к происходящим в отрасли процессам. Но не могу согласиться с основным выводом. Никакого разворота, скорее всего, не произойдет. Будет фрагментация. Проекты, где ведутся профессиональные процессы разработки без привлечения шальных денег будут обособляться от модных, но бесполезных проектов, где форма превалирует над содержанием. Этот процесс давно можно наблюдать в науке. Есть люди, ведущие научные исследования, а есть люди, продающие циркониевые браслеты, и они между собой практически нигде не пересекаются.
Полностью согласен. При этом задача IT — создать такую модель, в которой все хотелки заказчика будут работать. А сомнительные результаты будут достаточно подробно документированы.

У меня в одной системе было требование 1.45 = 2. Сделал так, как просили, но чтобы округление так работало, надо было зайти в настройки и явно включить эту фичу, которая по умолчанию была отключена.
Вот теперь мне все понятно. Спасибо.
Конечно, она в определенных областях незаменима. Но вот тип decimal в матфизике не нужен. Он предназначен именно для точного представления чисел, которые ведутся в десятичной системе счисления. Зачем в C# его плавающим сделали, для меня загадка. И вот этот эффект, когда в сходных случаях наблюдается разное поведение, меня удивляет. В double такого эффекта нет. Там, что 0.1 прибавить, что 100 — если точности не хватило, то число просто увеличено не будет.
Да уж. Я поражен. Оказывается, если к 79228162514264337593543950335m прибавить 0.1, то слагаемое потеряется. А если к этому же числу прибавить 1, то будет OverflowException. Плавающая точка — зло.
Понятно. Вы имели в виду 28 знак справа от точки, а я слева.

На stackoverflow пишут, что формат {:F} в C# всегда округляет до какой-то захардкоженной позиции. Именно поэтому я в примерах умножал на 10^15, чтобы нужные знаки получить. Я просто не нашел формат, в котором нет неявного округления.
Ага, вспомнил, что я хотел сказать. Я хотел возразить вот на это

Аналогично проблемен и Decimal из C#, и даже больше: если каким-то образом вылезли за его 28 цифр, то там даже inexact exception не будет: он не умеет жаловаться на такое.

Decimal выкидывает Exception.

decimal d0 = 79228162514264337593543950335m;
decimal d1 = d0 + 1; // OverflowException
Что касается покупки-продажи. Речь идет чисто о внутренней реализации. На табло можно надписать что угодно, все равно это никто не читает. А внутри, в коде, вместо терминов покупка-продажа должны быть точные нейтральные термины, которые тяжело спутать.

У меня был реальный случай, когда одна половина команды считала, что операция обозначает покупку иностранной валюты у клиента за рубли, а другая половина команды была уверена, что это покупка валюты у компании. Чтобы разобраться подняли все документы. Везде было слово «покупка», но нигде не уточнялось, кто у кого покупает. Причем, в некоторых согласованных всеми участниками документах были разночтения в проводках. Т. е. даже по проводкам однозначно нельзя было смысл восстановить.

Ну и известный инцидент, когда в одном серьезном банке курсы забили наоборот, в результате можно было купить доллары и тут же их продать дороже, тоже связан с неоднозначностью терминологии.
round(0.1) продемонстрировать не получилось. Я думаю, это какой-то крайний случай, когда получается точное число. Зато на 0.33 все предсказуемо

C#
double d = Math.Round(0.33d, 2);
d *= 10d;
d -= 3d;
d *= 10d;
d -= 3d;
Console.WriteLine(d); // 2.66453525910038E-15


Исключение при переполнении целой части не выбрасывается, вы правы. Я спутал с decimal.
Если вызвать round(0.1d) на выходе будет число, в котором все равно останется мусор после 15-го знака.

В C# я проверял — выскакивает ArithmeticOverflowException. А вот Java проглатывает.
А давайте еще упростим. Дебет всегда увеличивает дебет. Кредит всегда увеличивает кредит.
Это ж творчество. Тут каждый художник пишет в своем неповторимом стиле.
У меня там внутри класса Sum поле amount.
А потом уходишь в минус и гуляешь без денег по Парижу в поисках, чего бы пожрать…

Эх, как же скучно я живу.
Конечно, объект ExchangeRate может содержать много дополнительных методов, в том числе и расчет суммы в валюте списания от фиксированной суммы валюты зачисления, но смысл его полей при этом не поменяется. Будет как-то так:

public Sum howManyClientShouldGive(Sum clientWants) {
    if (!clientWants.getCurrency().equals(clientTakes.getCurrency())) {
        throw new IllegalArgumentException();
    }
    BigDecimal amount = clinetWants.getAmount().multiply(clientGives.getAmount())
            .divide(clinetTakes.getAmount(), PRECISION, BigDecimal.ROUND_HALF_UP);
    return new Sum(amount, clientGives.getCurrency());
}
Вообще да, mutable BigDecimal был бы очень полезен. Так как каждое значение в новый объект запихивать может быть очень накладно. Его можно для своих нужд быстренько сделать или готовый скачать.

Я, пожалуй, погорячился насчет экономии, но ради производительности double применять все равно не стоит.
Так ведь нельзя клиенту по этому же курсу продать USD за EUR. Это будет убыток банку. В этом-то то и фишка моей технологии. Нужно создать другой курс с параметрами clientGives: EUR, clientTakes: USD. И там цифры будут другие. Хотя, если вы готовы по тому же курсу в обратную сторону торговать, можно просто переставить значения местами, но это уже будет не бизнес, а благотворительность.

Курс обмена — односторонний, именно поэтому он является вектором.
если счет активный, то дебет это плюс

Когда все суммы положительные, то не нужен ни плюс, ни минус. Поэтому я считаю, что моя модель проще. Мне не нужно ничего запоминать.

У вас дебет — это плюс? Т. е. вы от кассы считаете? Вам так удобно?

Если бы я использовал плюс-минус, то у меня дебет был бы минус.
В яве можно добавить модификатор strictfp, чтобы эти граблей обойти.
Точно. А в оракле double вообще только в десятке появился.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Registered
Activity