fix amount arithmetic
This commit is contained in:
parent
2760591d4d
commit
268ca99244
@ -105,6 +105,7 @@ export interface ReserveCreationInfo {
|
|||||||
mintInfo: IMintInfo;
|
mintInfo: IMintInfo;
|
||||||
selectedDenoms: Denomination[];
|
selectedDenoms: Denomination[];
|
||||||
withdrawFee: AmountJson;
|
withdrawFee: AmountJson;
|
||||||
|
overhead: AmountJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ export namespace Amounts {
|
|||||||
saturated: boolean;
|
saturated: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMaxAmount(currency: string) {
|
function getMaxAmount(currency: string): AmountJson {
|
||||||
return {
|
return {
|
||||||
currency,
|
currency,
|
||||||
value: Number.MAX_SAFE_INTEGER,
|
value: Number.MAX_SAFE_INTEGER,
|
||||||
@ -165,25 +166,39 @@ export namespace Amounts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function add(first: AmountJson, ...rest: AmountJson[]): Result {
|
export function getZero(currency: string): AmountJson {
|
||||||
let currency = first.currency;
|
return {
|
||||||
let value = first.value + Math.floor(first.fraction / 1e6);
|
currency,
|
||||||
if (value > Number.MAX_SAFE_INTEGER) {
|
value: 0,
|
||||||
return {amount: getMaxAmount(currency), saturated: true};
|
fraction: 0,
|
||||||
}
|
}
|
||||||
let fraction = first.fraction;
|
}
|
||||||
for (let x of rest) {
|
|
||||||
if (x.currency !== currency) {
|
|
||||||
throw Error(`Mismatched currency: ${x.currency} and ${currency}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
fraction = (fraction + x.fraction) % 1e6;
|
export function add(first: AmountJson, ...rest: AmountJson[]): Result {
|
||||||
value = value + x.value + (Math.floor(fraction + x.fraction) / 1e6);
|
const doit = () => {
|
||||||
|
let currency = first.currency;
|
||||||
|
let value = first.value + Math.floor(first.fraction / 1e6);
|
||||||
if (value > Number.MAX_SAFE_INTEGER) {
|
if (value > Number.MAX_SAFE_INTEGER) {
|
||||||
return {amount: getMaxAmount(currency), saturated: true};
|
return {amount: getMaxAmount(currency), saturated: true};
|
||||||
}
|
}
|
||||||
}
|
let fraction = first.fraction % 1e6;
|
||||||
return {amount: {currency, value, fraction}, saturated: false};
|
for (let x of rest) {
|
||||||
|
if (x.currency !== currency) {
|
||||||
|
throw Error(`Mismatched currency: ${x.currency} and ${currency}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = value + x.value + Math.floor((fraction + x.fraction) / 1e6);
|
||||||
|
fraction = (fraction + x.fraction) % 1e6;
|
||||||
|
if (value > Number.MAX_SAFE_INTEGER) {
|
||||||
|
return {amount: getMaxAmount(currency), saturated: true};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {amount: {currency, value, fraction}, saturated: false};
|
||||||
|
};
|
||||||
|
console.log("adding", first, "and", rest);
|
||||||
|
let ret = doit();
|
||||||
|
console.log("result is", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -199,7 +214,7 @@ export namespace Amounts {
|
|||||||
return {amount: {currency, value: 0, fraction: 0}, saturated: true};
|
return {amount: {currency, value: 0, fraction: 0}, saturated: true};
|
||||||
}
|
}
|
||||||
value--;
|
value--;
|
||||||
fraction = +1e6;
|
fraction += 1e6;
|
||||||
}
|
}
|
||||||
console.assert(fraction >= b.fraction);
|
console.assert(fraction >= b.fraction);
|
||||||
fraction -= b.fraction;
|
fraction -= b.fraction;
|
||||||
@ -211,30 +226,51 @@ export namespace Amounts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function cmp(a: AmountJson, b: AmountJson): number {
|
export function cmp(a: AmountJson, b: AmountJson): number {
|
||||||
if (a.currency !== b.currency) {
|
const doit = () => {
|
||||||
throw Error(`Mismatched currency: ${a.currency} and ${b.currency}`);
|
if (a.currency !== b.currency) {
|
||||||
}
|
throw Error(`Mismatched currency: ${a.currency} and ${b.currency}`);
|
||||||
let av = a.value + Math.floor(a.fraction / 1e6);
|
}
|
||||||
let af = a.fraction % 1e6;
|
let av = a.value + Math.floor(a.fraction / 1e6);
|
||||||
let bv = b.value + Math.floor(b.fraction / 1e6);
|
let af = a.fraction % 1e6;
|
||||||
let bf = b.fraction % 1e6;
|
let bv = b.value + Math.floor(b.fraction / 1e6);
|
||||||
switch (true) {
|
let bf = b.fraction % 1e6;
|
||||||
case av < bv:
|
switch (true) {
|
||||||
return -1;
|
case av < bv:
|
||||||
case av > bv:
|
return -1;
|
||||||
return 1;
|
case av > bv:
|
||||||
case af < bf:
|
return 1;
|
||||||
return -1;
|
case af < bf:
|
||||||
case af > bf:
|
return -1;
|
||||||
return 1;
|
case af > bf:
|
||||||
case af == bf:
|
return 1;
|
||||||
return 0;
|
case af == bf:
|
||||||
default:
|
return 0;
|
||||||
throw Error("assertion failed");
|
default:
|
||||||
|
throw Error("assertion failed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("comparing", a, "and", b);
|
||||||
|
let res = doit();
|
||||||
|
console.log("result:", res);
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function copy(a: AmountJson): AmountJson {
|
||||||
|
return {
|
||||||
|
value: a.value,
|
||||||
|
fraction: a.fraction,
|
||||||
|
currency: a.currency,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isNonZero(a: AmountJson) {
|
||||||
|
return a.value > 0 || a.fraction > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface Notifier {
|
export interface Notifier {
|
||||||
notify();
|
notify();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user