release 1.14pre1
[descalc.git] / 35_unitconv.pm
1 # unit convertor for DCT, by Shiar
2
3 # 1.14.1 200701310504 - exact cd/dvd size
4 # 1.14.0 200501261830 - units can have different offsets, so we can convert ^C/^F
5 # 1.13.1 200501071420 - added cd/dvd sizes to data storage
6 # 1.13.0 200411042100 - changed calls addmenu() and redraw()
7 # 1.11.0 200410291000 - use redraw()
8 # 1.10.5 200410151900 - data storage units (8 total, including LOC)
9 # 1.10.4 200410132300 - hp49 units for mass
10 # 1.10.3 200410130000 - fix error when run without menu module
11 # 1.10.2 200410122200 - adds submenus with all units
12 # 1.10.1 200410122030 - hp49 units for area, volume, time, speed, force, energy, power
13 # 1.09.2 200410112205 - all code moved here as well
14 # 1.09.1 200410022305 - moved %unit specs from 1.9 main
15
16 use strict;
17 use warnings;
18 use utf8;
19
20 addmenu("main", "unit");
21
22 my %unit;  # unit table (build below)
23 my $i = 0;  # unit group counter (temporary)
24 do {
25         $i++;  # next group
26         my $title = shift @$_;  # first element is group title, no unit
27         addmenu("unit", $title, map "_$_->[0]", @$_);
28         $unit{$_->[0]} = {
29                 type=>$i, name=>$_->[0], val=>$_->[1], desc=>$_->[2], diff=>$_->[3]
30         } for @$_;
31 } for (
32         [
33                 "length",
34                 ['m', 1, "metre"],
35                 ['cm', .01, "centimeter"],
36                 ['mm', .001, "millimeter"],
37                 ['yd', .0254*36, "yard"],
38                 ['ft', .0254*12, "feet"],
39                 ['in', .0254, "inch"],
40                 ['Mpc', 3.085_677_581_3*10**22, "Mega parsec"],
41                 ['pc', 3.085_677_581_3*10**16, "parsec"], # 180*60*60/pi au
42                 ['lyr', 299_792_458*86_400*365.25, "light-year"], # c0*(seconds/year) - 9.46052840488e+15
43                 ['au', 149_597_870.691*30, "astronomical unit"],
44                 ['km', 1000, "kilometer"],
45                 ['mi', .0254*12*5280, "international mile"],
46                 ['nmi', 1852, "nautical mile"],
47                 ['miUS', 1200/3937*5280, "US statute mile"],
48                 ['chain', .0254*12*66, "Gunter's chain"],
49                 ['rd', .0254*198, "rod/pole/perch"],
50                 ['fath', .0254*72, "fathom"],
51                 ['ftUS', 1200/3937, "survey foot"],
52                 ['Mil', 2.54e-5, "Mil/thou"],
53                 ['μ', 1e-6, "micron"], # μm
54                 ['Å', 1e-10, "ångström"], # .1nm
55                 ['fermi', 1e-15, "fermi"], # 1fm
56 #               ['a0', .291_772_083*10**-11*19e-20, "atomic unit of length"],
57 #               ['ell', .0254*45, "ell"],
58 #               ['rope', .0254*12*20, "rope"],
59 #               TI86 order: mm cm m in ft  yd km mile mmile lt-yr  mil Ang fermi rod fath
60         ], # lengths
61         [
62                 "area",
63                 ['m²', 1, "square metre"],
64                 ['cm²', .01**2, "square centimetre"],
65                 ['b', 1e-28, "barn"],
66                 ['yd²', (.0254*36)**2, "square yard"],
67                 ['ft²', (.0254*12)**2, "square feet"],
68                 ['in²', (.0254)**2, "square inch"],
69                 ['km²', 1_000_000, "square kilometre"],
70                 ['ha', 10_000, "hectare"],
71                 ['a', 100, "are"],
72                 ['mi²', (.0254*12*5280)**2, "square mile"],
73                 ['miUS²', (1200/3937*5280)**2, "square statute mile"],
74                 ['acre', (.0254*12*66)**2*10, "acre"],
75 #               ['chain²', (.0254*12*66)**2, "square Gunter's chain"],
76 #               ['ba', .0254**2*12, "board"],
77         ], # area
78         [
79                 "volume", #todo
80                 ['m³', 1, "cubic metre"],
81 #               ['st', 0, "stere"],
82                 ['cm³', 1e-6, "cubic centimetre"],
83                 ['yd³', (.0254*36)**3, "cubic yard"],
84                 ['ft³', (.0254*12)**3, "cubic feet"],
85                 ['in³', (.0254)**3, "cubic inch"],
86                 ['l', 100, "litre"],
87                 ['galUK', .045_460_9, "Imperial gallon"],
88                 ['galC', 0, "Canadian gallon"],
89                 ['gal', 0, "US gallon"],
90                 ['qt', 0, "quart"],
91                 ['pt', 0, "pint"],
92                 ['ml', 100e6, "mililitre"],
93                 ['cu', 0, "US cup"],
94                 ['ozfl', 0, "US fluid ounce"],
95                 ['ozUK', 0, "UK fluid ounce"],
96                 ['tbsp', 0, "tablespoon"],
97                 ['tsp', 0, "teaspoon"],
98                 ['bbl', 0, "barrel"],
99                 ['bu', 0, "bushel"],
100                 ['pk', 0, "peck"],
101                 ['fbm', 0, "board foot"],
102         ], # volume
103         [
104                 "time",
105                 ['yr', 365.2425*86_400, "year (Gregorian)"],
106                 ['d', 86_400, "day"],
107                 ['h', 3_600, "hour"],
108                 ['min', 60, "minute"],
109                 ['s', 1, "second"],
110 #               ['Hz', 1, "hertz"],
111                 ['week', 604_800, "week"], # new
112 #               ['au', 2.418_884_254e-17, "atomic unit of time"], # a[0]/(α*c)
113         ], # time
114         [
115                 "speed",
116                 ['m/s', 1, "meter per second"],
117                 ['cm/s', 100, "centimeter per second"],
118                 ['ft/s', 8.466_667e-5, "feet per second"],
119                 ['kph', 2.777_778e-1, "kilometer per hour"],
120                 ['mph', .447_04, "mile per hour"],
121 #               ['mph', .447_041, "statute mile per hour"],
122                 ['knot', .514_444, "nautical miles per hour"],
123                 ['c', 2.997_924_58e8, "speed of light in vacuum"],
124 #               ['ga', 0, "acceleration of gravity"],
125         ], # speed
126         [
127                 "mass",
128                 ['kg', 1, "kilogram"],
129                 ['g', 1e-3, "gram"],
130                 ['Lb', .453_592_37, "avoirdupois pound"],
131                 ['oz', 28.349_523_125, "ounce"],
132                 ['slug', 14.593_903, "slug"],
133                 ['lbt', .373_241_721_6, "Troy pound"],
134                 ['ton', 907.184_74, "short ton"],
135                 ['tonUK', 1016.046_908_8, "long ton"],
136                 ['t', 1000, "tonne (metric ton)"],
137                 ['ozt', .031_103_476_8, "Troy ounce"],
138                 ['ct', 64.798_91e-6*19/6, "carat"], # 3+1/6 gr
139 #               ['kt', 200e-6, "metric carat"], # new
140                 ['grain', 64.798_91e-6, "grain"],
141                 ['u', 1.660_538_73e-27 * 13e-35, "unified atomic mass"],
142 #               ['mol', 0, "mole"], # mole = g/u
143         ], # mass
144         [
145                 "force",
146                 ['N', 1, "newton"], # kg*m/s²
147                 ['dyn', 1e-5, "dyne"],
148                 ['gf', 9_806.65, "gram-force"],
149                 ['kip', 4.448_221_615_260_500_0, "kilopound-force"],
150                 ['lbf', 4.448_221_615_260_5, "pound-force"],
151                 ['pdl', .138_254_954_376, "poundal"], # lb*ft/s²
152                 ['kgf', 9.806_65, "kilogram-force/grave"],
153         ], # force
154         [
155                 "energy",
156                 ['J', 1, "joule"], # N*m
157                 ['erg', 1e-7, "erg"], # g*cm²/s²
158                 ['Kcal', 4_186.8, "kilocalorie"],
159                 ['Cal', 4.186_8, "calorie"],
160                 ['Btu', 1_055.055_852_62, "International table btu"],
161                 ['ft*lbf', 1.355_817_948_331_400_4, "foot-pound"],
162                 ['therm', 105_505_585.262, "EEC therm"],
163                 ['MeV', 1/6.241_509_629_152_65e12, "mega electron-volt"],
164                 ['eV', 1/6.241_509_629_152_65e18, "electron-volt"],
165         ], # energy
166         [
167                 "power",
168                 ['W', 1, "watt"],
169                 ['hp', 735.498_75, "horse power"],
170         ], # power
171 #       [
172 #               "pressure",
173 #       ], # pressure
174         [
175                 "temperature", #todo
176                 ['°C', 1, "degree Celsius", 273.15],
177                 ['°F', 5/9, "degree Fahrenheit", 459.67],
178                 ['K', 1, "Kelvin"],
179                 ['°R', 5/9, "degree Rankine"],
180         ], # temperature
181 #       [], # electric current
182 #       [], # angle
183 #       [], # light
184 #       [], # radiation
185 #       [], # viscosity
186
187         [
188                 "data storage", # memory
189                 ['B', 1, "byte"],
190                 ['kB', 1024, "kilobyte"],
191                 ['MB', 1024**2, "megabyte"],
192                 ['GB', 1024**3, "gigabyte"],
193                 ['TB', 1024**4, "terabyte"],
194                 ['bit', 1/8, "bit/octet"],
195                 ['Mbit', 1024**2/8, "megabit"],
196                 ['LOC', 19e12, 'Library of Congress'], # est. 17-20TB
197                 ['CD', 359_847*2048, 'max CD-ROM (700MB) data'],
198                 ['DVD', 2_295_104*2048, 'max DVD-ROM data'],
199         ],
200 ); # units table
201
202 push @{$hook{precmd}}, sub {
203         if ($_ =~ /^_/) {{
204                 $_ = $unit{substr $_, 1} or next;
205                 if (exists $val{unit} and $val{unit}{type}==$_->{type}) {
206                         unshift @stack, $val{i} if defined $val{i};
207                         $stack[0] += $val{unit}{diff} if $val{unit}{diff};
208                         $stack[0] *= delete($val{unit})->{val} / $_->{val};
209                         $stack[0] -= $_->{diff} if $_->{diff};
210                         redraw(stack=>1);
211                         undef %val;
212                 } # convert
213                 else {
214                         $val{unit} = $_;
215                 } # set source unit
216                 return 1;
217         }} # conversion
218 }; # precmd
219
220 push @{$hook{postentry}}, sub {
221         exists $val{unit} && '_'.$val{unit}{name};
222 }; # showentry
223
224 return {
225         author  => "Shiar",
226         title   => "unit convertor",
227         version => "1.14.01",
228 };
229