webmcp

annotate framework/env/format/decimal.lua @ 382:810c020b0da4

Reverted changes to mondelefant_result_index and mondelefant_result_newindex C-functions (proxying of JSON document)
author jbe
date Mon Nov 16 18:31:49 2015 +0100 (2015-11-16)
parents 9fdfb27f8e67
children
rev   line source
jbe/bsw@0 1 --[[--
jbe/bsw@0 2 text = -- text with the value formatted as decimal number
jbe/bsw@0 3 format.decimal(
jbe/bsw@0 4 value, -- a number, a fraction or nil
jbe/bsw@0 5 {
jbe/bsw@0 6 nil_as = nil_text, -- text to be returned for a nil value
jbe/bsw@0 7 digits = digits, -- digits before decimal point
jbe/bsw@0 8 precision = precision, -- digits after decimal point
jbe/bsw@0 9 decimal_shift = decimal_shift -- divide the value by 10^decimal_shift (setting true uses precision)
jbe/bsw@0 10 }
jbe/bsw@0 11 )
jbe/bsw@0 12
jbe/bsw@0 13 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'.
jbe/bsw@0 14
jbe/bsw@0 15 --]]--
jbe/bsw@0 16
jbe/bsw@0 17 function format.decimal(value, options)
jbe/bsw@0 18 -- TODO: more features
jbe/bsw@0 19 local options = options or {}
jbe/bsw@0 20 local special_chars = charset.get_data().special_chars
jbe/bsw@0 21 local f
jbe/bsw@0 22 if value == nil then
jbe/bsw@0 23 return options.nil_as or ""
jbe/bsw@0 24 elseif atom.has_type(value, atom.number) then
jbe/bsw@0 25 f = value
jbe/bsw@0 26 elseif atom.has_type(value, atom.fraction) then
jbe/bsw@0 27 f = value.float
jbe/bsw@0 28 else
jbe/bsw@0 29 error("Value passed to format.decimal(...) is neither a number nor a fraction nor nil.")
jbe/bsw@0 30 end
jbe/bsw@0 31 local digits = options.digits
jbe/bsw@0 32 local precision = options.precision or 0
jbe/bsw@0 33 local decimal_shift = options.decimal_shift or 0
jbe/bsw@0 34 if decimal_shift == true then
jbe/bsw@0 35 decimal_shift = precision
jbe/bsw@0 36 end
jbe/bsw@0 37 f = f / 10 ^ decimal_shift
jbe/bsw@0 38 local negative
jbe/bsw@0 39 local absolute
jbe/bsw@0 40 if f < 0 then
jbe/bsw@0 41 absolute = -f
jbe/bsw@0 42 negative = true
jbe/bsw@0 43 else
jbe/bsw@0 44 absolute = f
jbe/bsw@0 45 negative = false
jbe/bsw@0 46 end
jbe/bsw@0 47 absolute = absolute + 0.5 / 10 ^ precision
jbe/bsw@0 48 local int = math.floor(absolute)
jbe/bsw@0 49 if not atom.is_integer(int) then
jbe/bsw@0 50 if f > 0 then
jbe/bsw@0 51 return "+" .. special_chars.inf_sign
jbe/bsw@0 52 elseif f < 0 then
jbe/bsw@0 53 return minus_sign .. special_chars.inf_sign
jbe/bsw@0 54 else
jbe/bsw@0 55 return "NaN"
jbe/bsw@0 56 end
jbe/bsw@0 57 end
jbe/bsw@0 58 local int_str = tostring(int)
jbe/bsw@0 59 if digits then
jbe/bsw@0 60 while #int_str < digits do
jbe/bsw@0 61 int_str = "0" .. int_str
jbe/bsw@0 62 end
jbe/bsw@0 63 end
jbe/bsw@0 64 if precision > 0 then
jbe/bsw@0 65 local decimal_point =
jbe/bsw@0 66 options.decimal_point or
jbe/bsw@0 67 locale.get('decimal_point') or '.'
jbe/bsw@0 68 local frac_str = tostring(math.floor((absolute - int) * 10 ^ precision))
jbe/bsw@0 69 while #frac_str < precision do
jbe/bsw@0 70 frac_str = "0" .. frac_str
jbe/bsw@0 71 end
jbe/bsw@0 72 assert(#frac_str == precision, "Assertion failed in format.float(...).") -- should not happen
jbe/bsw@0 73 if negative then
jbe/bsw@0 74 return special_chars.minus_sign .. int_str .. decimal_point .. frac_str
jbe/bsw@0 75 elseif options.show_plus then
jbe/bsw@0 76 return "+" .. int_str .. decimal_point .. frac_str
jbe/bsw@0 77 else
jbe/bsw@0 78 return int_str .. decimal_point .. frac_str
jbe/bsw@0 79 end
jbe/bsw@0 80 else
jbe/bsw@0 81 if negative then
jbe/bsw@0 82 return special_chars.minus_sign .. int
jbe/bsw@0 83 elseif options.show_plus then
jbe/bsw@0 84 return "+" .. int_str
jbe/bsw@0 85 else
jbe/bsw@0 86 return int_str
jbe/bsw@0 87 end
jbe/bsw@0 88 end
jbe/bsw@0 89 end

Impressum / About Us