release 1.10.6
[descalc.git] / 35_unitconv.pm
diff --git a/35_unitconv.pm b/35_unitconv.pm
new file mode 100644 (file)
index 0000000..1374ccf
--- /dev/null
@@ -0,0 +1,209 @@
+# unit convertor for DCT, by Shiar
+
+# 1.09.1 200410022305 - moved %unit specs from 1.9 main
+# 1.09.2 200410112205 - all code moved here as well
+# 1.10.1 200410122030 - hp49 units for area, volume, time, speed, force, energy, power
+#     .2         2200 - adds submenus with all units
+#     .3     10130000 - fix error when run without menu module
+#     .4     10132300 - hp49 units for mass
+
+use strict;
+use warnings;
+use utf8;
+
+my $menugroup = addmenu(["main", 0], "unit") if defined &addmenu;
+
+my %unit;  # unit table (build below)
+my $i = 0;  # unit group counter (temporary)
+do {
+       $i++;  # next group
+       my $title = shift @$_;  # first element is group title, no unit
+       addmenu(["unit", $menugroup], $title, map "_$_->[0]", @$_) if defined &addmenu;
+       $unit{$_->[0]} = {
+               type=>$i, name=>$_->[0], val=>$_->[1], desc=>$_->[2], diff=>$_->[3]
+       } for @$_;
+} for (
+       [
+               "length",
+               ['m', 1, "metre"],
+               ['cm', .01, "centimeter"],
+               ['mm', .001, "millimeter"],
+               ['yd', .0254*36, "yard"],
+               ['ft', .0254*12, "feet"],
+               ['in', .0254, "inch"],
+               ['Mpc', 3.085_677_581_3*10**22, "Mega parsec"],
+               ['pc', 3.085_677_581_3*10**16, "parsec"], # 180*60*60/pi au
+               ['lyr', 299_792_458*86_400*365.25, "light-year"], # c0*(seconds/year) - 9.46052840488e+15
+               ['au', 149_597_870.691*30, "astronomical unit"],
+               ['km', 1000, "kilometer"],
+               ['mi', .0254*12*5280, "international mile"],
+               ['nmi', 1852, "nautical mile"],
+               ['miUS', 1200/3937*5280, "US statute mile"],
+               ['chain', .0254*12*66, "Gunter's chain"],
+               ['rd', .0254*198, "rod/pole/perch"],
+               ['fath', .0254*72, "fathom"],
+               ['ftUS', 1200/3937, "survey foot"],
+               ['Mil', 2.54e-5, "Mil/thou"],
+               ['μ', 1e-6, "micron"], # μm
+               ['Å', 1e-10, "ångström"], # .1nm
+               ['fermi', 1e-15, "fermi"], # 1fm
+#              ['a0', .291_772_083*10**-11*19e-20, "atomic unit of length"],
+#              ['ell', .0254*45, "ell"],
+#              ['rope', .0254*12*20, "rope"],
+#              TI86 order: mm cm m in ft  yd km mile mmile lt-yr  mil Ang fermi rod fath
+       ], # lengths
+       [
+               "area",
+               ['m²', 1, "square metre"],
+               ['cm²', .01**2, "square centimetre"],
+               ['b', 1e-28, "barn"],
+               ['yd²', (.0254*36)**2, "square yard"],
+               ['ft²', (.0254*12)**2, "square feet"],
+               ['in²', (.0254)**2, "square inch"],
+               ['km²', 1_000_000, "square kilometre"],
+               ['ha', 10_000, "hectare"],
+               ['a', 100, "are"],
+               ['mi²', (.0254*12*5280)**2, "square mile"],
+               ['miUS²', (1200/3937*5280)**2, "square statute mile"],
+               ['acre', (.0254*12*66)**2*10, "acre"],
+#              ['chain²', (.0254*12*66)**2, "square Gunter's chain"],
+#              ['ba', .0254**2*12, "board"],
+       ], # area
+       [
+               "volume", #todo
+               ['m³', 1, "cubic metre"],
+#              ['st', 0, "stere"],
+               ['cm³', 1e-6, "cubic centimetre"],
+               ['yd³', (.0254*36)**3, "cubic yard"],
+               ['ft³', (.0254*12)**3, "cubic feet"],
+               ['in³', (.0254)**3, "cubic inch"],
+               ['l', 100, "litre"],
+               ['galUK', .045_460_9, "Imperial gallon"],
+               ['galC', 0, "Canadian gallon"],
+               ['gal', 0, "US gallon"],
+               ['qt', 0, "quart"],
+               ['pt', 0, "pint"],
+               ['ml', 100e6, "mililitre"],
+               ['cu', 0, "US cup"],
+               ['ozfl', 0, "US fluid ounce"],
+               ['ozUK', 0, "UK fluid ounce"],
+               ['tbsp', 0, "tablespoon"],
+               ['tsp', 0, "teaspoon"],
+               ['bbl', 0, "barrel"],
+               ['bu', 0, "bushel"],
+               ['pk', 0, "peck"],
+               ['fbm', 0, "board foot"],
+       ], # volume
+       [
+               "time",
+               ['yr', 365.2425*86_400, "year (Gregorian)"],
+               ['d', 86_400, "day"],
+               ['h', 3_600, "hour"],
+               ['min', 60, "minute"],
+               ['s', 1, "second"],
+#              ['Hz', 1, "hertz"],
+               ['week', 604_800, "week"], # new
+#              ['au', 2.418_884_254e-17, "atomic unit of time"], # a[0]/(α*c)
+       ], # time
+       [
+               "speed",
+               ['m/s', 1, "meter per second"],
+               ['cm/s', 100, "centimeter per second"],
+               ['ft/s', 8.466_667e-5, "feet per second"],
+               ['kph', 2.777_778e-1, "kilometer per hour"],
+               ['mph', .447_04, "mile per hour"],
+#              ['mph', .447_041, "statute mile per hour"],
+               ['knot', .514_444, "nautical miles per hour"],
+               ['c', 2.997_924_58e8, "speed of light in vacuum"],
+#              ['ga', 0, "acceleration of gravity"],
+       ], # speed
+       [
+               "mass",
+               ['kg', 1, "kilogram"],
+               ['g', 1e-3, "gram"],
+               ['Lb', .453_592_37, "avoirdupois pound"],
+               ['oz', 28.349_523_125, "ounce"],
+               ['slug', 14.593_903, "slug"],
+               ['lbt', .373_241_721_6, "Troy pound"],
+               ['ton', 907.184_74, "short ton"],
+               ['tonUK', 1016.046_908_8, "long ton"],
+               ['t', 1000, "tonne (metric ton)"],
+               ['ozt', .031_103_476_8, "Troy ounce"],
+               ['ct', 64.798_91e-6*19/6, "carat"], # 3+1/6 gr
+#              ['kt', 200e-6, "metric carat"], # new
+               ['grain', 64.798_91e-6, "grain"],
+               ['u', 1.660_538_73e-27 * 13e-35, "unified atomic mass"],
+#              ['mol', 0, "mole"], # mole = g/u
+       ], # mass
+       [
+               "force",
+               ['N', 1, "newton"], # kg*m/s²
+               ['dyn', 1e-5, "dyne"],
+               ['gf', 9_806.65, "gram-force"],
+               ['kip', 4.448_221_615_260_500_0, "kilopound-force"],
+               ['lbf', 4.448_221_615_260_5, "pound-force"],
+               ['pdl', .138_254_954_376, "poundal"], # lb*ft/s²
+               ['kgf', 9.806_65, "kilogram-force/grave"],
+       ], # force
+       [
+               "energy",
+               ['J', 1, "joule"], # N*m
+               ['erg', 1e-7, "erg"], # g*cm²/s²
+               ['Kcal', 4_186.8, "kilocalorie"],
+               ['Cal', 4.186_8, "calorie"],
+               ['Btu', 1_055.055_852_62, "International table btu"],
+               ['ft*lbf', 1.355_817_948_331_400_4, "foot-pound"],
+               ['therm', 105_505_585.262, "EEC therm"],
+               ['MeV', 1/6.241_509_629_152_65e12, "mega electron-volt"],
+               ['eV', 1/6.241_509_629_152_65e18, "electron-volt"],
+       ], # energy
+       [
+               "power",
+               ['W', 1, "watt"],
+               ['hp', 735.498_75, "horse power"],
+       ], # power
+#      [
+#              "pressure",
+#      ], # pressure
+       [
+               "temperature", #todo
+               ['°C', 1, "degree Celsius", 273.15],
+               ['°F', 5/9, "degree Fahrenheit", 459.67],
+               ['K', 1, "Kelvin"],
+               ['°R', 5/9, "degree Rankine"],
+       ], # temperature
+#      [], # electric current
+#      [], # angle
+#      [], # light
+#      [], # radiation
+#      [], # viscosity
+); # units table
+
+push @{$hook{precmd}}, sub {
+       if ($_ =~ /^_/) {{
+               $_ = $unit{substr $_, 1} or next;
+               if (exists $val{unit} and $val{unit}{type}==$_->{type}) {
+                       unshift @stack, $val{i} if defined $val{i};
+#                      $stack[0] -= $_->{diff} if $_->{diff};
+#                      $stack[0] += $val{unit}{diff}*$val{unit}{val}/$_->{val} if $val{unit}{diff};
+                       $stack[0] *= delete($val{unit})->{val} / $_->{val};
+                       showstack();
+                       undef %val;
+               } # convert
+               else {
+                       $val{unit} = $_;
+               } # set source unit
+               return 1;
+       }} # conversion
+}; # precmd
+
+push @{$hook{postentry}}, sub {
+       exists $val{unit} && '_'.$val{unit}{name};
+}; # showentry
+
+return {
+       author  => "Shiar",
+       title   => "unit convertor",
+       version => "1.10.4",
+};
+