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