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;
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();
}