Module:Convert: Difference between revisions

fix default precision when input includes a fraction
(oh what complex webs we weave ... bad input unit includes no input unit)
(fix default precision when input includes a fraction)
Line 1,026:
 
local function extract_fraction(parms, text, negative)
-- If text represents a fraction, return value, show, spelled where
-- value, show, spelled, denominator
-- where
-- value is a number (value of the fraction in argument text)
-- show is a string (formatted text for display of an input value,
-- and is spelled if wanted and possible)
-- spelled is true if show was spelled
-- denominator is value of the denominator in the fraction
-- Otherwise, return nil.
-- Input uses en digits and '.' decimal mark (input has been translated).
Line 1,107 ⟶ 1,110:
wikitext = spell_number(parms, wholestr, numsign .. numstr, denstr) or wikitext
end
return value, wikitext, do_spell, denominator
end
 
Line 1,141 ⟶ 1,144:
end
local isnegative, propersign = false, '' -- most common case
local singular, show, denominator
local value = tonumber(clean)
if value then
Line 1,173 ⟶ 1,176:
local spelled
if not no_fraction then
value, show, spelled, denominator = extract_fraction(parms, clean, isnegative)
end
if value == nil then
Line 1,211 ⟶ 1,214:
clean = clean,
show = show,
denominator = denominator,
}
end
Line 1,375 ⟶ 1,379:
utype = in_unit_table.utype,
scale = subunit.scale, -- scale of last (least significant) unit
valinfo = { { value = total, clean = subinfo.clean, denominator = subinfo.denominator } },
composite = composite_units,
default = default or in_unit_table.default
Line 1,656 ⟶ 1,660:
end
 
local function default_precision(invalue, inclean, denominator, outvalue, in_current, out_current, extra)
-- Return a default value for precision (an integer like 2, 0, -2).
-- If denominator is not nil, it is the value of the denominator in inclean.
-- Code follows procedures used in old template.
local fudge = 1e-14 -- {{Order of magnitude}} adds this, so we do too
Line 1,671 ⟶ 1,676:
end
end
if denominator and denominator > 0 then
-- Count digits after decimal mark, handling cases like '12.345e6'.
prec = math.max(log10(denominator), 1)
local exponent
local integer, dot, fraction, expstr = inclean:match('^(%d*)(%.?)(%d*)(.*)')
local e = expstr:sub(1, 1)
local boost = 0 -- can increase default precision
if e == 'e' or e == 'E' then
exponent = tonumber(expstr:sub(2))
elseif expstr:find('/', 1, true) then
boost = 1 -- any input fraction is regarded as one extra digit of precision
end
if dot == '' then
prec = subunit_ignore_trailing_zero and 0 or -integer:match('0*$'):len()
else
-- Count digits after decimal mark, handling cases like '12.345e6'.
prec = #fraction
local exponent
end
local integer, dot, fraction, expstr = inclean:match('^(%d*)(%.?)(%d*)(.*)')
if exponent then
local e = expstr:sub(1, 1)
-- So '1230' and '1.23e3' both give prec = -1, and '0.00123' and '1.23e-3' give 5.
precif e == prec'e' or e == -'E' exponentthen
exponent = tonumber(expstr:sub(2))
end
if e == 'e' orif edot == 'E' then
prec = subunit_ignore_trailing_zero and 0 or -integer:match('0*$'):len()
else
prec = #fraction
end
if exponent then
-- So '1230' and '1.23e3' both give prec = -1, and '0.00123' and '1.23e-3' give 5.
prec = prec - exponent
end
end
if in_current.istemperature and out_current.istemperature then
Line 1,732 ⟶ 1,738:
minprec = extra.minprec or minprec
end
return math.max(floor(prec + adjust + boost), minprec)
end
 
Line 1,891 ⟶ 1,897:
else
use_default_precision = true
precision = default_precision(invalue, inclean, info.denominator, outvalue, in_current, out_current, extra)
end
end
Anonymous user