static void exchangeNXTForCurrency( Transaction transaction, Account account, final long currencyId, final long rateNQT, long units) { long extraUnits = 0; long remainingAmountNQT = Math.multiplyExact(units, rateNQT); List<CurrencySellOffer> currencySellOffers = new ArrayList<>(); try (DbIterator<CurrencySellOffer> offers = CurrencySellOffer.getOffers( new ValidOffersDbClause(currencyId, rateNQT, false), 0, -1, " ORDER BY rate ASC, creation_height ASC, transaction_height ASC, transaction_index ASC ")) { for (CurrencySellOffer offer : offers) { currencySellOffers.add(offer); } } for (CurrencySellOffer offer : currencySellOffers) { if (remainingAmountNQT == 0) { break; } long curUnits = Math.min( Math.min(remainingAmountNQT / offer.getRateNQT(), offer.getSupply()), offer.getLimit()); if (curUnits == 0) { continue; } long curAmountNQT = Math.multiplyExact(curUnits, offer.getRateNQT()); extraUnits = Math.addExact(extraUnits, curUnits); remainingAmountNQT = Math.subtractExact(remainingAmountNQT, curAmountNQT); offer.decreaseLimitAndSupply(curUnits); long excess = offer.getCounterOffer().increaseSupply(curUnits); Account counterAccount = Account.getAccount(offer.getAccountId()); counterAccount.addToBalanceNQT(curAmountNQT); counterAccount.addToUnconfirmedBalanceNQT( Math.addExact( Math.multiplyExact( curUnits - excess, offer.getRateNQT() - offer.getCounterOffer().getRateNQT()), Math.multiplyExact(excess, offer.getRateNQT()))); counterAccount.addToCurrencyUnits(currencyId, -curUnits); Exchange.addExchange( transaction, currencyId, offer, offer.getAccountId(), account.getId(), curUnits); } account.addToCurrencyAndUnconfirmedCurrencyUnits(currencyId, extraUnits); account.addToBalanceNQT(-(Math.multiplyExact(units, rateNQT) - remainingAmountNQT)); account.addToUnconfirmedBalanceNQT(remainingAmountNQT); }
long increaseSupply(long delta) { long excess = Math.max(Math.addExact(supply, Math.subtractExact(delta, limit)), 0); supply += delta - excess; return excess; }
@Override public Integer minus(Integer other) { try { return new ScalableInt32(Math.subtractExact(this.value, ((ScalableInt32) other).value)); } catch (ClassCastException e) { return promoteNext().minus(other); } catch (ArithmeticException e) { return promoteNext().minus(other); } }
/** * Returns a copy of this period with the specified period subtracted. * * <p>This operates separately on the years, months, days and the normalized time. There is no * further normalization beyond the normalized time. * * <p>For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days" returns "-1 * years, 4 months and 1 day". * * <p>This instance is immutable and unaffected by this method call. * * @param amountToSubtract the period to subtract, not null * @return a {@code Period} based on this period with the requested period subtracted, not null * @throws ArithmeticException if numeric overflow occurs */ public Period minus(Period amountToSubtract) { return create( Math.subtractExact(years, amountToSubtract.years), Math.subtractExact(months, amountToSubtract.months), Math.subtractExact(days, amountToSubtract.days)); }