fix amount arithmetic

This commit is contained in:
Florian Dold 2016-02-22 23:12:57 +01:00
parent 2760591d4d
commit 268ca99244

View File

@ -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 getZero(currency: string): AmountJson {
return {
currency,
value: 0,
fraction: 0,
}
}
export function add(first: AmountJson, ...rest: AmountJson[]): Result { export function add(first: AmountJson, ...rest: AmountJson[]): Result {
const doit = () => {
let currency = first.currency; let currency = first.currency;
let value = first.value + Math.floor(first.fraction / 1e6); 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; let fraction = first.fraction % 1e6;
for (let x of rest) { for (let x of rest) {
if (x.currency !== currency) { if (x.currency !== currency) {
throw Error(`Mismatched currency: ${x.currency} and ${currency}`); throw Error(`Mismatched currency: ${x.currency} and ${currency}`);
} }
value = value + x.value + Math.floor((fraction + x.fraction) / 1e6);
fraction = (fraction + x.fraction) % 1e6; fraction = (fraction + x.fraction) % 1e6;
value = value + x.value + (Math.floor(fraction + x.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};
} }
} }
return {amount: {currency, value, fraction}, saturated: false}; 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,6 +226,7 @@ export namespace Amounts {
} }
export function cmp(a: AmountJson, b: AmountJson): number { export function cmp(a: AmountJson, b: AmountJson): number {
const doit = () => {
if (a.currency !== b.currency) { if (a.currency !== b.currency) {
throw Error(`Mismatched currency: ${a.currency} and ${b.currency}`); throw Error(`Mismatched currency: ${a.currency} and ${b.currency}`);
} }
@ -232,9 +248,29 @@ export namespace Amounts {
default: default:
throw Error("assertion failed"); 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();
} }