-
Notifications
You must be signed in to change notification settings - Fork 307
Open
Description
I am running into a bug. I have 0.001 inches and the toBest option is converting to miles.
I read through the source code and I think there's an edge case for values that are -1 < x < 1 such as 0.001 that causes the toBest to find the highest specificty of units (miles) instead of the lowest most relevant unit (inches) specifically when cutOffNumber is 0
import convert from 'convert-units'; // "convert-units": "^2.3.4"
function main(){
const LESS_THEN_1_VAL = 0.001;
const FROM_UNIT = "in";
const converted = convert(LESS_THEN_1_VAL).from(FROM_UNIT).toBest({
cutOffNumber: 0,
});
// OUTPUT:
// converted {
// val: 1.5782828282828283e-8,
// unit: 'mi',
// singular: 'Mile',
// plural: 'Miles'
// }
// expected to be whatever the most specific imperial unit is available is (such as 'in' or 'mil')
console.log("converted", converted)
}
main();Here is how I'm working around this in my codebase:
export const getCustomBest = (
value: number,
fromUnits: ConvertUnits,
toSystem: MeasurementSystem
): BestResult | null => {
const system =
convert().describe(fromUnits).system === MeasurementSystem.si
? undefined
: toSystem;
// try to get best using the standard convert lib
let converted = convert(value)
.from(fromUnits)
.toBest({
system,
exclude: EXCLUDED_UNITS,
cutOffNumber: value < 0 ? -1 : 1,
});
// handle -> -1 < x < 1
if (!converted) {
const conversionOptions: AnchoredBestResult[] = [];
const possibilities = convert()
.from(fromUnits)
.possibilities()
.filter((p) => !EXCLUDED_UNITS.includes(p));
for (const possibility of possibilities) {
const unit = convert().describe(possibility);
const unitDetails = convert().getUnit(possibility);
if (!unitDetails) {
continue;
}
if (unit.system === system) {
const result = convert(value).from(fromUnits).to(possibility);
conversionOptions.push({
val: result,
unit: possibility,
singular: unit.singular,
plural: unit.plural,
to_anchor: unitDetails.unit.to_anchor,
});
}
}
// pick the largest from the options -- if there are absolutely no options then return null
if (conversionOptions.length > 0) {
let best: AnchoredBestResult | null = null;
for (const option of conversionOptions) {
if (best
5ADE
=== null || option.to_anchor < best.to_anchor) {
best = option;
}
}
converted = best;
}
}
return converted;
};PS thanks for making this lib! It's much appreciated!
Metadata
Metadata
Assignees
Labels
No labels