webmcp

diff framework/env/format/decimal.lua @ 0:9fdfb27f8e67

Version 1.0.0
author jbe/bsw
date Sun Oct 25 12:00:00 2009 +0100 (2009-10-25)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/framework/env/format/decimal.lua	Sun Oct 25 12:00:00 2009 +0100
     1.3 @@ -0,0 +1,89 @@
     1.4 +--[[--
     1.5 +text =                             -- text with the value formatted as decimal number
     1.6 +format.decimal(
     1.7 +  value,                           -- a number, a fraction or nil
     1.8 +  {
     1.9 +    nil_as        = nil_text,      -- text to be returned for a nil value
    1.10 +    digits        = digits,        -- digits before decimal point
    1.11 +    precision     = precision,     -- digits after decimal point
    1.12 +    decimal_shift = decimal_shift  -- divide the value by 10^decimal_shift (setting true uses precision)
    1.13 +  }
    1.14 +)
    1.15 +
    1.16 +Formats a (floating point) number or a fraction as a decimal number. If a 'digits' option is set, the number of digits before the decimal point is increased up to the given count by preceding it with zeros. The digits after the decimal point are adjusted by the 'precision' parameter. The 'decimal_shift' parameter is useful, when fixed precision decimal numbers are stored as integers, as the given value will be divided by 10 to the power of the 'decimal_shift' value prior to formatting. Setting 'decimal_shift' to true will copy the value for 'precision'.
    1.17 +
    1.18 +--]]--
    1.19 +
    1.20 +function format.decimal(value, options)
    1.21 +  -- TODO: more features
    1.22 +  local options = options or {}
    1.23 +  local special_chars = charset.get_data().special_chars
    1.24 +  local f
    1.25 +  if value == nil then
    1.26 +    return options.nil_as or ""
    1.27 +  elseif atom.has_type(value, atom.number) then
    1.28 +    f = value
    1.29 +  elseif atom.has_type(value, atom.fraction) then
    1.30 +    f = value.float
    1.31 +  else
    1.32 +    error("Value passed to format.decimal(...) is neither a number nor a fraction nor nil.")
    1.33 +  end
    1.34 +  local digits = options.digits
    1.35 +  local precision = options.precision or 0
    1.36 +  local decimal_shift = options.decimal_shift or 0
    1.37 +  if decimal_shift == true then
    1.38 +    decimal_shift = precision
    1.39 +  end
    1.40 +  f = f / 10 ^ decimal_shift
    1.41 +  local negative
    1.42 +  local absolute
    1.43 +  if f < 0 then
    1.44 +    absolute = -f
    1.45 +    negative = true
    1.46 +  else
    1.47 +    absolute = f
    1.48 +    negative = false
    1.49 +  end
    1.50 +  absolute = absolute + 0.5 / 10 ^ precision
    1.51 +  local int = math.floor(absolute)
    1.52 +  if not atom.is_integer(int) then
    1.53 +    if f > 0 then
    1.54 +      return "+" .. special_chars.inf_sign
    1.55 +    elseif f < 0 then
    1.56 +      return minus_sign .. special_chars.inf_sign
    1.57 +    else
    1.58 +      return "NaN"
    1.59 +    end
    1.60 +  end
    1.61 +  local int_str = tostring(int)
    1.62 +  if digits then
    1.63 +    while #int_str < digits do
    1.64 +      int_str = "0" .. int_str
    1.65 +    end
    1.66 +  end
    1.67 +  if precision > 0 then
    1.68 +    local decimal_point =
    1.69 +      options.decimal_point or
    1.70 +      locale.get('decimal_point') or '.'
    1.71 +    local frac_str = tostring(math.floor((absolute - int) * 10 ^ precision))
    1.72 +    while #frac_str < precision do
    1.73 +      frac_str = "0" .. frac_str
    1.74 +    end
    1.75 +    assert(#frac_str == precision, "Assertion failed in format.float(...).")  -- should not happen
    1.76 +    if negative then
    1.77 +      return special_chars.minus_sign .. int_str .. decimal_point .. frac_str
    1.78 +    elseif options.show_plus then
    1.79 +      return "+" .. int_str .. decimal_point .. frac_str
    1.80 +    else
    1.81 +      return int_str .. decimal_point .. frac_str
    1.82 +    end
    1.83 +  else
    1.84 +    if negative then
    1.85 +      return special_chars.minus_sign .. int
    1.86 +    elseif options.show_plus then
    1.87 +      return "+" .. int_str
    1.88 +    else
    1.89 +      return int_str
    1.90 +    end
    1.91 +  end
    1.92 +end

Impressum / About Us