Class: Lisp::Format::Directives::ExpFP
- Defined in:
- lib/carat/lisp-format.rb
Overview
Represents the ~E (Exponential floating-point) directive. This outputs floating point values in what is known as exponential or scientific floating point format, such as 1.0e+3 for 1000.
Instance Attribute Summary
Attributes inherited from Directive
Instance Method Summary collapse
-
#execute(state) ⇒ Object
Outputs the argument using exponential floating-point format.
Methods inherited from Directive
Constructor Details
This class inherits a constructor from Lisp::Format::Directives::Directive
Instance Method Details
#execute(state) ⇒ Object
Outputs the argument using exponential floating-point format. The full form is
~w,d,e,k,overflowchar,padchar,exponentchar@E
with the following interpretations
w
(nil
)-
if non-
nil
, the output will be exactlyw
characters long, d
(nil
)-
if non-
nil
, this is the number of digits output after the decimal point (.
), e
(nil
)-
if non-
nil
, the exponent part of the output will be exactlye
characters long, k
(1)-
scaling factor - the number is first scaled using this value,
overflowchar
(nil
)-
if non-
nil
, this character is used when this directive would produce output longer than that specified with thew
directive, padchar
(?s)-
character to pad with if
w
is non-nil and output isn’t wide enough yet, exponentchar
(?e)-
character to use for exponent divider,
- @
-
numbers are always output with sign prepended.
An ArgumentError is raised if the argument is not a number or a string that can be converted to a number.
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 |
# File 'lib/carat/lisp-format.rb', line 1065 def execute(state) width = param(0, state, nil) digits = param(1, state, nil) edigits = param(2, state, nil) scale = param(3, state, 1) overflowchar = param(4, state, nil) padchar = param(5, state, ?\s).chr exponentchar = param(6, state, ?e).chr arg = state.next_arg if arg.respond_to? :to_f num = arg.to_f sign = (num >= 0 and at_mod?) ? '+' : '' exp = Math.log10(num.abs).floor - (scale - 1) exp_str = exponentchar + (exp >= 0 ? '+' : '-') + (edigits.nil? ? exp.abs.to_s : exp.abs.to_s.rjust(edigits, '0')) if digits.nil? and width.nil? and edigits.nil? str = sign + (num * (10 ** -exp)).to_s + exp_str else if digits.nil? prec = width - sign.length - ((num * (10 ** -exp)).to_s.index(/\./) + 1) - exp_str.length str = sign + sprintf("%#.#{prec}f", num) + exp_str else if scale > 0 if scale < digits + 2 prec = digits - scale + 1 else param_error 3, 'scale must be < digits + 2' end else prec = -scale + (digits + scale) end str = sign + sprintf("%#.#{prec}f", num * (10**-exp)) + exp_str end unless width.nil? if scale <= 0 and str.length > width str.sub!(/^([+-]?)0\./, '\1.') end str = str.rjust(width, padchar) if str.length < width end unless width.nil? and overflowchar.nil? if not edigits.nil? and (exp_str.length - 2) > edigits str = overflowchar.chr * width end end end state.output str elsif arg.respond_to? :to_int state.push_back_arg parameters = @params[0].nil? ? [] : [@params[0]] Factory.build(parameters, [], ?D, nil, @pos).execute(state) else arg_error 'argument is not a number or a number string' end end |