1 class MathPlugin < Plugin
28 def help(plugin, topic="")
29 "math <expression>, evaluate mathematical expression"
33 m.reply "incorrect usage: " + help(m.plugin)
39 expr.gsub!(/\b#{k}\b/, v)
42 # ruby doesn't like floating-point values without a 0
43 # in front of them, so find any non-digit followed by
44 # a .<digits> and insert a 0 before the .
45 expr.gsub!(/(\D|^)(\.\d+)/,'\10\2')
47 while expr =~ /(exp ([\w\d]+))/
49 val = Math.exp($2).to_s
50 expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
53 while expr =~ /^\s*(dec2hex\s*(\d+))\s*\?*/
55 val = sprintf("%x", $2)
56 expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
59 expr.gsub(/\be\b/, Math.exp(1).to_s)
61 while expr =~ /(log\s*((\d+\.?\d*)|\d*\.?\d+))\s*/
68 val = Math.log(res).to_s
71 expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
74 while expr =~ /(bin2dec ([01]+))/
76 val = join('', unpack('B*', pack('N', $2)))
78 expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
81 expr.gsub!(/ to the power of /, " ** ")
82 expr.gsub!(/ to the /, " ** ")
83 expr.gsub!(/\btimes\b/, "*")
84 expr.gsub!(/\bdiv(ided by)? /, "/ ")
85 expr.gsub!(/\bover /, "/ ")
86 expr.gsub!(/\bsquared/, "**2 ")
87 expr.gsub!(/\bcubed/, "**3 ")
88 expr.gsub!(/\bto\s+(\d+)(r?st|nd|rd|th)?( power)?/, '**\1 ')
89 expr.gsub!(/\bpercent of/, "*0.01*")
90 expr.gsub!(/\bpercent/, "*0.01")
91 expr.gsub!(/\% of\b/, "*0.01*")
92 expr.gsub!(/\%/, "*0.01")
93 expr.gsub!(/\bsquare root of (\d+(\.\d+)?)/, '\1 ** 0.5 ')
94 expr.gsub!(/\bcubed? root of (\d+(\.\d+)?)/, '\1 **(1.0/3.0) ')
95 expr.gsub!(/ of /, " * ")
96 expr.gsub!(/(bit(-| )?)?xor(\'?e?d( with))?/, "^")
97 expr.gsub!(/(bit(-| )?)?or(\'?e?d( with))?/, "|")
98 expr.gsub!(/bit(-| )?and(\'?e?d( with))?/, "& ")
99 expr.gsub!(/(plus|and)/, "+")
102 if (expr =~ /^\s*[-\d*+\s()\/^\.\|\&\*\!]+\s*$/ &&
103 expr !~ /^\s*\(?\d+\.?\d*\)?\s*$/ &&
105 expr !~ /^\s*[( )]+\s*$/)
108 debug "evaluating expression \"#{expr}\""
110 if answer =~ /^[-+\de\.]+$/
111 answer = sprintf("%1.12f", answer)
112 answer.gsub!(/\.?0+$/, "")
113 answer.gsub!(/(\.\d+)000\d+/, '\1')
114 if (answer.length > 30)
115 answer = "a number with >30 digits..."
119 rescue Exception => e
121 m.reply "illegal expression \"#{m.params}\""
125 m.reply "illegal expression \"#{m.params}\""
130 plugin = MathPlugin.new
131 plugin.register("math")
132 plugin.register("maths")