Importing usr.bin/units
No Minix-specific changes needed. Change-Id: I2a3411bf78d5e31875d577dcd6df68f76da98137
This commit is contained in:
parent
9068050135
commit
2106ea4754
9 changed files with 1861 additions and 1 deletions
|
@ -517,6 +517,7 @@
|
|||
./usr/bin/uncompress minix-sys
|
||||
./usr/bin/unexpand minix-sys
|
||||
./usr/bin/uniq minix-sys
|
||||
./usr/bin/units minix-sys
|
||||
./usr/bin/unlzma minix-sys
|
||||
./usr/bin/unstack minix-sys
|
||||
./usr/bin/unxz minix-sys
|
||||
|
@ -2076,6 +2077,7 @@
|
|||
./usr/man/man1/uncompress.1 minix-sys
|
||||
./usr/man/man1/unexpand.1 minix-sys
|
||||
./usr/man/man1/uniq.1 minix-sys
|
||||
./usr/man/man1/units.1 minix-sys
|
||||
./usr/man/man1/unlzma.1 minix-sys
|
||||
./usr/man/man1/unset.1 minix-sys
|
||||
./usr/man/man1/unxz.1 minix-sys
|
||||
|
@ -4636,6 +4638,7 @@
|
|||
./usr/share/misc/texinfo.dtd minix-sys
|
||||
./usr/share/misc/texinfo.tex minix-sys
|
||||
./usr/share/misc/texinfo.xsl minix-sys
|
||||
./usr/share/misc/units.lib minix-sys
|
||||
./usr/share/misc/zipcodes minix-sys
|
||||
./usr/share/mk minix-sys
|
||||
./usr/share/mk/bsd.clang-analyze.mk minix-sys
|
||||
|
|
|
@ -204,6 +204,7 @@
|
|||
2012/10/17 12:00:00,usr.bin/tr
|
||||
2012/10/17 12:00:00,usr.bin/tsort
|
||||
2010/10/06 07:59:18,usr.bin/uniq
|
||||
2013/10/23 12:00:00,usr.bin/units
|
||||
2013/10/14 12:00:00,usr.bin/unzip
|
||||
2013/10/14 12:00:00,usr.bin/users
|
||||
2012/10/17 12:00:00,usr.bin/wc
|
||||
|
|
|
@ -28,7 +28,7 @@ SUBDIR= \
|
|||
tee tic tput \
|
||||
tr tsort unexpand \
|
||||
toproto \
|
||||
uniq unzip users \
|
||||
uniq units unzip users \
|
||||
\
|
||||
wc whatis who \
|
||||
xargs xinstall yes
|
||||
|
|
11
usr.bin/units/Makefile
Normal file
11
usr.bin/units/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
|||
# $NetBSD: Makefile,v 1.6 1999/02/13 02:54:56 lukem Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= units
|
||||
.if ${MKSHARE} != "no"
|
||||
FILES= units.lib
|
||||
FILESDIR=/usr/share/misc
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
18
usr.bin/units/README
Normal file
18
usr.bin/units/README
Normal file
|
@ -0,0 +1,18 @@
|
|||
# $NetBSD: README,v 1.2 1996/04/06 06:00:59 thorpej Exp $
|
||||
|
||||
This is a program which I wrote as a clone of the UNIX 'units'
|
||||
command. I threw it together in a couple days, but it seems to work,
|
||||
with some restrictions. I have tested it under DOS with Borland C and
|
||||
Ultrix 4.2, and SunOS 4.1.
|
||||
|
||||
This program differs from the unix units program in the following
|
||||
ways:
|
||||
it can gracefully handle exponents larger than 9 in output
|
||||
it uses 'e' to denote exponentiation in numbers
|
||||
prefixes are listed in the units file
|
||||
it tries both -s and -es plurals
|
||||
it allows use of * for multiply and ^ for exponentiation in the input
|
||||
the output format is somewhat different
|
||||
|
||||
Adrian Mariano (adrian@cam.cornell.edu or mariano@geom.umn.edu)
|
||||
|
37
usr.bin/units/pathnames.h
Normal file
37
usr.bin/units/pathnames.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* $NetBSD: pathnames.h,v 1.6 2003/07/26 20:34:14 salo Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993 Christopher G. Demetriou
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed for the
|
||||
* NetBSD Project. See http://www.NetBSD.org/ for
|
||||
* information about NetBSD.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
|
||||
*/
|
||||
|
||||
#define _PATH_UNITSLIB "/usr/share/misc/units.lib"
|
229
usr.bin/units/units.1
Normal file
229
usr.bin/units/units.1
Normal file
|
@ -0,0 +1,229 @@
|
|||
.\" $NetBSD: units.1,v 1.21 2013/07/20 21:40:01 wiz Exp $
|
||||
.Dd January 6, 2013
|
||||
.Dt UNITS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm units
|
||||
.Nd conversion program
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl Llqv
|
||||
.Op Fl f Ar filename
|
||||
.Oo
|
||||
.Op Ar count
|
||||
.Ar from-unit to-unit
|
||||
.Oc
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
converts quantities expression in various scales to
|
||||
their equivalents in other scales.
|
||||
.Nm
|
||||
can only handle multiplicative scale changes.
|
||||
It cannot convert Centigrade to Fahrenheit, for example.
|
||||
.Pp
|
||||
The following options and arguments are supported:
|
||||
.Bl -tag -width "-fXfilenameX" -offset indent
|
||||
.It Fl f Ar filename
|
||||
Specifies the name of the units data file to load.
|
||||
.It Fl l No or Fl L
|
||||
List all unit definitions to the standard output,
|
||||
instead of performing any conversions.
|
||||
The result may include error messages and comments, beginning with
|
||||
.Ql \&/ .
|
||||
.Pp
|
||||
With the
|
||||
.Fl l
|
||||
option, unit definitions will be listed in a format
|
||||
almost identical to the the units data file that was loaded,
|
||||
except that comments will be removed, spacing may be changed,
|
||||
and lines may be re-ordered.
|
||||
.Pp
|
||||
With the
|
||||
.Fl L
|
||||
option, all unit definitions will be reduced to a form that
|
||||
depends on only a few primitive units (such as
|
||||
.Sy m , kg , sec ) .
|
||||
.It Fl q
|
||||
Suppresses prompting of the user for units and the display of statistics
|
||||
about the number of units loaded.
|
||||
.It Fl v
|
||||
Prints the version number.
|
||||
.It Oo Ar count Oc Ar from-unit Ar to-unit
|
||||
Allows a single unit conversion to be done directly from the command
|
||||
line.
|
||||
No prompting will occur.
|
||||
.Nm
|
||||
will print out only the result of this single conversion.
|
||||
Specifying
|
||||
.Ar count
|
||||
and
|
||||
.Ar from-unit
|
||||
as two separate arguments is equivalent to embedding both parts
|
||||
inside a single
|
||||
.Ar from-unit
|
||||
argument, with the parts separated by a space.
|
||||
.El
|
||||
.Pp
|
||||
.Nm
|
||||
works interactively by prompting the user for input:
|
||||
.Bd -literal
|
||||
You have: meters
|
||||
You want: feet
|
||||
* 3.2808399
|
||||
/ 0.3048
|
||||
|
||||
You have: cm^3
|
||||
You want: gallons
|
||||
* 0.00026417205
|
||||
/ 3785.4118
|
||||
.Ed
|
||||
.Pp
|
||||
Powers of units can be specified using the
|
||||
.Dq \&^
|
||||
character as shown in the example, or by simple concatenation:
|
||||
.Dq cm3
|
||||
is equivalent to
|
||||
.Dq cm^3 .
|
||||
Multiplication of units can be specified by using spaces, a dash or
|
||||
an asterisk.
|
||||
Division of units is indicated by the slash
|
||||
.Pq Sq \&/ .
|
||||
Note that multiplication has a higher precedence than division,
|
||||
so
|
||||
.Dq m/s/s
|
||||
is the same as
|
||||
.Dq m/s^2
|
||||
or
|
||||
.Dq "m/s s" .
|
||||
If the user enters incompatible unit types, the
|
||||
.Nm
|
||||
program will print a message indicating that the units are not
|
||||
conformable and it will display the reduced form for each unit:
|
||||
.Bd -literal
|
||||
You have: ergs/hour
|
||||
You want: fathoms kg^2 / day
|
||||
conformability error
|
||||
2.7777778e-11 kg m^2 / sec^3
|
||||
2.1166667e-05 kg^2 m / sec
|
||||
.Ed
|
||||
.Pp
|
||||
The conversion information is read from a units data file.
|
||||
The default
|
||||
file includes definitions for most familiar units, abbreviations and
|
||||
metric prefixes.
|
||||
Some constants of nature included are:
|
||||
.Bl -tag -width mercury -compact -offset indent
|
||||
.It pi
|
||||
ratio of circumference to diameter
|
||||
.It c
|
||||
speed of light
|
||||
.It e
|
||||
charge on an electron
|
||||
.It g
|
||||
acceleration of gravity
|
||||
.It force
|
||||
same as g
|
||||
.It mole
|
||||
Avogadro's number
|
||||
.It water
|
||||
pressure per unit height of water
|
||||
.It mercury
|
||||
pressure per unit height of mercury
|
||||
.It au
|
||||
astronomical unit
|
||||
.El
|
||||
.Pp
|
||||
.Dq pound
|
||||
is a unit of mass.
|
||||
Compound names are run together
|
||||
so
|
||||
.Dq poundforce
|
||||
is a unit of force.
|
||||
British units that differ from their
|
||||
US counterparts are prefixed with
|
||||
.Dq br ,
|
||||
and currency is prefixed with
|
||||
its country name:
|
||||
.Dq belgiumfranc ,
|
||||
.Dq britainpound .
|
||||
When searching for
|
||||
a unit, if the specified string does not appear exactly as a unit
|
||||
name, then the
|
||||
.Nm
|
||||
program will try to remove a trailing
|
||||
.Dq s
|
||||
or a trailing
|
||||
.Dq es
|
||||
and check again for a match.
|
||||
.Pp
|
||||
All of these definitions can be read in the standard units file, or you
|
||||
can supply your own file.
|
||||
A unit is specified on a single line by
|
||||
giving its name and an equivalence.
|
||||
One should be careful to define
|
||||
new units in terms of old ones so that a reduction leads to the
|
||||
primitive units which are marked with
|
||||
.Sq \&!
|
||||
characters.
|
||||
.Nm
|
||||
will not detect infinite loops that could be caused
|
||||
by careless unit definitions.
|
||||
.Pp
|
||||
Prefixes are defined in the same way as standard units, but with
|
||||
a trailing dash at the end of the prefix name.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/share/misc/units.lib -compact
|
||||
.It Pa /usr/share/misc/units.lib
|
||||
the standard units library
|
||||
.El
|
||||
.Sh AUTHORS
|
||||
.An Adrian Mariano Aq Mt adrian@cam.cornell.edu
|
||||
or
|
||||
.Aq mariano@geom.umn.edu
|
||||
.Sh CAVEATS
|
||||
While
|
||||
.Nm
|
||||
can be used as a calculator for many unit-related computations,
|
||||
caution is required: many computations require additional constant
|
||||
factors deriving from the physics (or chemistry or whatever) of the
|
||||
situation.
|
||||
As these factors are dimensionless,
|
||||
.Nm
|
||||
cannot itself either provide them or warn the user when they have been
|
||||
forgotten.
|
||||
For example, one joule is one kilogram meter squared per second
|
||||
squared, by definition; however, the kinetic energy of a one-kilogram
|
||||
object moving at one meter per second is half a joule, not one joule,
|
||||
because of a dimensionless factor that arises from integration.
|
||||
.Pp
|
||||
Also, some pairs of units that have the same dimensionality are
|
||||
nonetheless used to measure different things and attempting to convert
|
||||
between them may require additional fudge factors or be entirely
|
||||
meaningless.
|
||||
For example, torque and energy have the same dimensionality, but
|
||||
attempting to convert torque in newton-meters to energy in joules is
|
||||
nonsensical.
|
||||
There is no practical way for
|
||||
.Nm
|
||||
to warn about these issues either.
|
||||
.Sh BUGS
|
||||
The effect of including a
|
||||
.Sq \&/
|
||||
in a prefix is surprising.
|
||||
.Pp
|
||||
Exponents entered by the user can be only one digit.
|
||||
You can work around this by multiplying several terms.
|
||||
.Pp
|
||||
The user must use
|
||||
.Sq \&|
|
||||
to indicate division of numbers and
|
||||
.Sq \&/
|
||||
to indicate division of symbols.
|
||||
This distinction should not be necessary.
|
||||
.Pp
|
||||
The program contains various arbitrary limits on the length
|
||||
of the units converted and on the length of the data file.
|
||||
.Pp
|
||||
The program should use a hash table to store units so that
|
||||
it doesn't take so long to load the units list and check
|
||||
for duplication.
|
910
usr.bin/units/units.c
Normal file
910
usr.bin/units/units.c
Normal file
|
@ -0,0 +1,910 @@
|
|||
/* $NetBSD: units.c,v 1.24 2013/01/06 00:19:13 wiz Exp $ */
|
||||
|
||||
/*
|
||||
* units.c Copyright (c) 1993 by Adrian Mariano (adrian@cam.cornell.edu)
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
* Disclaimer: This software is provided by the author "as is". The author
|
||||
* shall not be liable for any damages caused in any way by this software.
|
||||
*
|
||||
* I would appreciate (though I do not require) receiving a copy of any
|
||||
* improvements you might make to this program.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
|
||||
#define VERSION "1.0"
|
||||
|
||||
#ifndef UNITSFILE
|
||||
#define UNITSFILE _PATH_UNITSLIB
|
||||
#endif
|
||||
|
||||
#define MAXUNITS 1000
|
||||
#define MAXPREFIXES 50
|
||||
|
||||
#define MAXSUBUNITS 500
|
||||
|
||||
#define PRIMITIVECHAR '!'
|
||||
|
||||
static int precision = 8; /* for printf with "%.*g" format */
|
||||
|
||||
static const char *errprefix = NULL; /* if not NULL, then prepend this
|
||||
* to error messages and send them to
|
||||
* stdout instead of stderr.
|
||||
*/
|
||||
|
||||
static const char *powerstring = "^";
|
||||
|
||||
static struct {
|
||||
const char *uname;
|
||||
const char *uval;
|
||||
} unittable[MAXUNITS];
|
||||
|
||||
struct unittype {
|
||||
const char *numerator[MAXSUBUNITS];
|
||||
const char *denominator[MAXSUBUNITS];
|
||||
double factor;
|
||||
};
|
||||
|
||||
struct {
|
||||
const char *prefixname;
|
||||
const char *prefixval;
|
||||
} prefixtable[MAXPREFIXES];
|
||||
|
||||
|
||||
static const char *NULLUNIT = "";
|
||||
|
||||
static int unitcount;
|
||||
static int prefixcount;
|
||||
|
||||
|
||||
static int addsubunit(const char *[], const char *);
|
||||
static int addunit(struct unittype *, const char *, int);
|
||||
static void cancelunit(struct unittype *);
|
||||
static int compare(const void *, const void *);
|
||||
static int compareproducts(const char **, const char **);
|
||||
static int compareunits(struct unittype *, struct unittype *);
|
||||
static int compareunitsreciprocal(struct unittype *, struct unittype *);
|
||||
static int completereduce(struct unittype *);
|
||||
static void initializeunit(struct unittype *);
|
||||
static void readerror(int);
|
||||
static void readunits(const char *);
|
||||
static int reduceproduct(struct unittype *, int);
|
||||
static int reduceunit(struct unittype *);
|
||||
static void showanswer(struct unittype *, struct unittype *);
|
||||
static void showunit(struct unittype *);
|
||||
static void sortunit(struct unittype *);
|
||||
__dead static void usage(void);
|
||||
static void zeroerror(void);
|
||||
static char *dupstr(const char *);
|
||||
static const char *lookupunit(const char *);
|
||||
|
||||
static char *
|
||||
dupstr(const char *str)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = strdup(str);
|
||||
if (!ret)
|
||||
err(3, "Memory allocation error");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mywarnx(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
if (errprefix) {
|
||||
/* warn to stdout, with errprefix prepended */
|
||||
printf("%s", errprefix);
|
||||
vprintf(fmt, args);
|
||||
printf("%s", "\n");
|
||||
} else {
|
||||
/* warn to stderr */
|
||||
vwarnx(fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void
|
||||
readerror(int linenum)
|
||||
{
|
||||
mywarnx("Error in units file '%s' line %d", UNITSFILE, linenum);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
readunits(const char *userfile)
|
||||
{
|
||||
FILE *unitfile;
|
||||
char line[80], *lineptr;
|
||||
int len, linenum, i, isdup;
|
||||
|
||||
unitcount = 0;
|
||||
linenum = 0;
|
||||
|
||||
if (userfile) {
|
||||
unitfile = fopen(userfile, "rt");
|
||||
if (!unitfile)
|
||||
err(1, "Unable to open units file '%s'", userfile);
|
||||
}
|
||||
else {
|
||||
unitfile = fopen(UNITSFILE, "rt");
|
||||
if (!unitfile) {
|
||||
char *direc, *env;
|
||||
char filename[1000];
|
||||
char separator[2];
|
||||
|
||||
env = getenv("PATH");
|
||||
if (env) {
|
||||
if (strchr(env, ';'))
|
||||
strlcpy(separator, ";",
|
||||
sizeof(separator));
|
||||
else
|
||||
strlcpy(separator, ":",
|
||||
sizeof(separator));
|
||||
direc = strtok(env, separator);
|
||||
while (direc) {
|
||||
strlcpy(filename, "", sizeof(filename));
|
||||
strlcat(filename, direc,
|
||||
sizeof(filename));
|
||||
strlcat(filename, "/",
|
||||
sizeof(filename));
|
||||
strlcat(filename, UNITSFILE,
|
||||
sizeof(filename));
|
||||
unitfile = fopen(filename, "rt");
|
||||
if (unitfile)
|
||||
break;
|
||||
direc = strtok(NULL, separator);
|
||||
}
|
||||
}
|
||||
if (!unitfile)
|
||||
errx(1, "Can't find units file '%s'",
|
||||
UNITSFILE);
|
||||
}
|
||||
}
|
||||
while (!feof(unitfile)) {
|
||||
if (!fgets(line, 79, unitfile))
|
||||
break;
|
||||
linenum++;
|
||||
lineptr = line;
|
||||
if (*lineptr == '/')
|
||||
continue;
|
||||
lineptr += strspn(lineptr, " \n\t");
|
||||
len = strcspn(lineptr, " \n\t");
|
||||
lineptr[len] = 0;
|
||||
if (!strlen(lineptr))
|
||||
continue;
|
||||
if (lineptr[strlen(lineptr) - 1] == '-') { /* it's a prefix */
|
||||
if (prefixcount == MAXPREFIXES) {
|
||||
mywarnx(
|
||||
"Memory for prefixes exceeded in line %d",
|
||||
linenum);
|
||||
continue;
|
||||
}
|
||||
lineptr[strlen(lineptr) - 1] = 0;
|
||||
for (isdup = 0, i = 0; i < prefixcount; i++) {
|
||||
if (!strcmp(prefixtable[i].prefixname,
|
||||
lineptr)) {
|
||||
isdup = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isdup) {
|
||||
mywarnx(
|
||||
"Redefinition of prefix '%s' on line %d ignored",
|
||||
lineptr, linenum);
|
||||
continue;
|
||||
}
|
||||
prefixtable[prefixcount].prefixname = dupstr(lineptr);
|
||||
lineptr += len + 1;
|
||||
if (!strlen(lineptr)) {
|
||||
readerror(linenum);
|
||||
continue;
|
||||
}
|
||||
lineptr += strspn(lineptr, " \n\t");
|
||||
len = strcspn(lineptr, "\n\t");
|
||||
lineptr[len] = 0;
|
||||
prefixtable[prefixcount++].prefixval = dupstr(lineptr);
|
||||
}
|
||||
else { /* it's not a prefix */
|
||||
if (unitcount == MAXUNITS) {
|
||||
mywarnx("Memory for units exceeded in line %d",
|
||||
linenum);
|
||||
continue;
|
||||
}
|
||||
for (isdup = 0, i = 0; i < unitcount; i++) {
|
||||
if (!strcmp(unittable[i].uname, lineptr)) {
|
||||
isdup = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isdup) {
|
||||
mywarnx(
|
||||
"Redefinition of unit '%s' on line %d ignored",
|
||||
lineptr, linenum);
|
||||
continue;
|
||||
}
|
||||
unittable[unitcount].uname = dupstr(lineptr);
|
||||
lineptr += len + 1;
|
||||
lineptr += strspn(lineptr, " \n\t");
|
||||
if (!strlen(lineptr)) {
|
||||
readerror(linenum);
|
||||
continue;
|
||||
}
|
||||
len = strcspn(lineptr, "\n\t");
|
||||
lineptr[len] = 0;
|
||||
unittable[unitcount++].uval = dupstr(lineptr);
|
||||
}
|
||||
}
|
||||
fclose(unitfile);
|
||||
}
|
||||
|
||||
static void
|
||||
initializeunit(struct unittype * theunit)
|
||||
{
|
||||
theunit->factor = 1.0;
|
||||
theunit->numerator[0] = theunit->denominator[0] = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
addsubunit(const char *product[], const char *toadd)
|
||||
{
|
||||
const char **ptr;
|
||||
|
||||
for (ptr = product; *ptr && *ptr != NULLUNIT; ptr++);
|
||||
if (ptr >= product + MAXSUBUNITS) {
|
||||
mywarnx("Memory overflow in unit reduction");
|
||||
return 1;
|
||||
}
|
||||
if (!*ptr)
|
||||
*(ptr + 1) = 0;
|
||||
*ptr = dupstr(toadd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
showunit(struct unittype * theunit)
|
||||
{
|
||||
const char **ptr;
|
||||
int printedslash;
|
||||
int counter = 1;
|
||||
|
||||
printf("\t%.*g", precision, theunit->factor);
|
||||
for (ptr = theunit->numerator; *ptr; ptr++) {
|
||||
if (ptr > theunit->numerator && **ptr &&
|
||||
!strcmp(*ptr, *(ptr - 1)))
|
||||
counter++;
|
||||
else {
|
||||
if (counter > 1)
|
||||
printf("%s%d", powerstring, counter);
|
||||
if (**ptr)
|
||||
printf(" %s", *ptr);
|
||||
counter = 1;
|
||||
}
|
||||
}
|
||||
if (counter > 1)
|
||||
printf("%s%d", powerstring, counter);
|
||||
counter = 1;
|
||||
printedslash = 0;
|
||||
for (ptr = theunit->denominator; *ptr; ptr++) {
|
||||
if (ptr > theunit->denominator && **ptr &&
|
||||
!strcmp(*ptr, *(ptr - 1)))
|
||||
counter++;
|
||||
else {
|
||||
if (counter > 1)
|
||||
printf("%s%d", powerstring, counter);
|
||||
if (**ptr) {
|
||||
if (!printedslash)
|
||||
printf(" /");
|
||||
printedslash = 1;
|
||||
printf(" %s", *ptr);
|
||||
}
|
||||
counter = 1;
|
||||
}
|
||||
}
|
||||
if (counter > 1)
|
||||
printf("%s%d", powerstring, counter);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
zeroerror(void)
|
||||
{
|
||||
mywarnx("Unit reduces to zero");
|
||||
}
|
||||
|
||||
/*
|
||||
Adds the specified string to the unit.
|
||||
Flip is 0 for adding normally, 1 for adding reciprocal.
|
||||
|
||||
Returns 0 for successful addition, nonzero on error.
|
||||
*/
|
||||
|
||||
static int
|
||||
addunit(struct unittype * theunit, const char *toadd, int flip)
|
||||
{
|
||||
char *scratch, *savescr;
|
||||
char *item;
|
||||
char *divider, *slash;
|
||||
int doingtop;
|
||||
|
||||
savescr = scratch = dupstr(toadd);
|
||||
for (slash = scratch + 1; *slash; slash++)
|
||||
if (*slash == '-' &&
|
||||
(tolower((unsigned char)*(slash - 1)) != 'e' ||
|
||||
!strchr(".0123456789", *(slash + 1))))
|
||||
*slash = ' ';
|
||||
slash = strchr(scratch, '/');
|
||||
if (slash)
|
||||
*slash = 0;
|
||||
doingtop = 1;
|
||||
do {
|
||||
item = strtok(scratch, " *\t\n/");
|
||||
while (item) {
|
||||
if (strchr("0123456789.", *item)) {
|
||||
/* item starts with a number */
|
||||
char *endptr;
|
||||
double num;
|
||||
|
||||
divider = strchr(item, '|');
|
||||
if (divider) {
|
||||
*divider = 0;
|
||||
num = strtod(item, &endptr);
|
||||
if (!num) {
|
||||
zeroerror();
|
||||
return 1;
|
||||
}
|
||||
if (endptr != divider) {
|
||||
/* "6foo|2" is an error */
|
||||
mywarnx("Junk before '|'");
|
||||
return 1;
|
||||
}
|
||||
if (doingtop ^ flip)
|
||||
theunit->factor *= num;
|
||||
else
|
||||
theunit->factor /= num;
|
||||
num = strtod(divider + 1, &endptr);
|
||||
if (!num) {
|
||||
zeroerror();
|
||||
return 1;
|
||||
}
|
||||
if (doingtop ^ flip)
|
||||
theunit->factor /= num;
|
||||
else
|
||||
theunit->factor *= num;
|
||||
if (*endptr) {
|
||||
/* "6|2foo" is like "6|2 foo" */
|
||||
item = endptr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
num = strtod(item, &endptr);
|
||||
if (!num) {
|
||||
zeroerror();
|
||||
return 1;
|
||||
}
|
||||
if (doingtop ^ flip)
|
||||
theunit->factor *= num;
|
||||
else
|
||||
theunit->factor /= num;
|
||||
if (*endptr) {
|
||||
/* "3foo" is like "3 foo" */
|
||||
item = endptr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* item is not a number */
|
||||
int repeat = 1;
|
||||
|
||||
if (strchr("23456789",
|
||||
item[strlen(item) - 1])) {
|
||||
repeat = item[strlen(item) - 1] - '0';
|
||||
item[strlen(item) - 1] = 0;
|
||||
}
|
||||
for (; repeat; repeat--)
|
||||
if (addsubunit(doingtop ^ flip ? theunit->numerator : theunit->denominator, item))
|
||||
return 1;
|
||||
}
|
||||
item = strtok(NULL, " *\t/\n");
|
||||
}
|
||||
doingtop--;
|
||||
if (slash) {
|
||||
scratch = slash + 1;
|
||||
}
|
||||
else
|
||||
doingtop--;
|
||||
} while (doingtop >= 0);
|
||||
free(savescr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
compare(const void *item1, const void *item2)
|
||||
{
|
||||
return strcmp(*(const char * const *) item1,
|
||||
*(const char * const *) item2);
|
||||
}
|
||||
|
||||
static void
|
||||
sortunit(struct unittype * theunit)
|
||||
{
|
||||
const char **ptr;
|
||||
int count;
|
||||
|
||||
for (count = 0, ptr = theunit->numerator; *ptr; ptr++, count++);
|
||||
qsort(theunit->numerator, count, sizeof(char *), compare);
|
||||
for (count = 0, ptr = theunit->denominator; *ptr; ptr++, count++);
|
||||
qsort(theunit->denominator, count, sizeof(char *), compare);
|
||||
}
|
||||
|
||||
static void
|
||||
cancelunit(struct unittype * theunit)
|
||||
{
|
||||
const char **den, **num;
|
||||
int comp;
|
||||
|
||||
den = theunit->denominator;
|
||||
num = theunit->numerator;
|
||||
|
||||
while (*num && *den) {
|
||||
comp = strcmp(*den, *num);
|
||||
if (!comp) {
|
||||
/* if (*den!=NULLUNIT) free(*den);
|
||||
if (*num!=NULLUNIT) free(*num);*/
|
||||
*den++ = NULLUNIT;
|
||||
*num++ = NULLUNIT;
|
||||
}
|
||||
else if (comp < 0)
|
||||
den++;
|
||||
else
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Looks up the definition for the specified unit.
|
||||
Returns a pointer to the definition or a null pointer
|
||||
if the specified unit does not appear in the units table.
|
||||
*/
|
||||
|
||||
static char buffer[100]; /* buffer for lookupunit answers with
|
||||
prefixes */
|
||||
|
||||
static const char *
|
||||
lookupunit(const char *unit)
|
||||
{
|
||||
int i;
|
||||
char *copy;
|
||||
|
||||
for (i = 0; i < unitcount; i++) {
|
||||
if (!strcmp(unittable[i].uname, unit))
|
||||
return unittable[i].uval;
|
||||
}
|
||||
|
||||
if (unit[strlen(unit) - 1] == '^') {
|
||||
copy = dupstr(unit);
|
||||
copy[strlen(copy) - 1] = 0;
|
||||
for (i = 0; i < unitcount; i++) {
|
||||
if (!strcmp(unittable[i].uname, copy)) {
|
||||
strlcpy(buffer, copy, sizeof(buffer));
|
||||
free(copy);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
free(copy);
|
||||
}
|
||||
if (unit[strlen(unit) - 1] == 's') {
|
||||
copy = dupstr(unit);
|
||||
copy[strlen(copy) - 1] = 0;
|
||||
for (i = 0; i < unitcount; i++) {
|
||||
if (!strcmp(unittable[i].uname, copy)) {
|
||||
strlcpy(buffer, copy, sizeof(buffer));
|
||||
free(copy);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
if (copy[strlen(copy) - 1] == 'e') {
|
||||
copy[strlen(copy) - 1] = 0;
|
||||
for (i = 0; i < unitcount; i++) {
|
||||
if (!strcmp(unittable[i].uname, copy)) {
|
||||
strlcpy(buffer, copy, sizeof(buffer));
|
||||
free(copy);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(copy);
|
||||
}
|
||||
for (i = 0; i < prefixcount; i++) {
|
||||
if (!strncmp(prefixtable[i].prefixname, unit,
|
||||
strlen(prefixtable[i].prefixname))) {
|
||||
unit += strlen(prefixtable[i].prefixname);
|
||||
if (!strlen(unit) || lookupunit(unit)) {
|
||||
strlcpy(buffer, prefixtable[i].prefixval,
|
||||
sizeof(buffer));
|
||||
strlcat(buffer, " ", sizeof(buffer));
|
||||
strlcat(buffer, unit, sizeof(buffer));
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
reduces a product of symbolic units to primitive units.
|
||||
The three low bits are used to return flags:
|
||||
|
||||
bit 0 (1) set on if reductions were performed without error.
|
||||
bit 1 (2) set on if no reductions are performed.
|
||||
bit 2 (4) set on if an unknown unit is discovered.
|
||||
*/
|
||||
|
||||
|
||||
#define ERROR 4
|
||||
|
||||
static int
|
||||
reduceproduct(struct unittype * theunit, int flip)
|
||||
{
|
||||
|
||||
const char *toadd;
|
||||
const char **product;
|
||||
int didsomething = 2;
|
||||
|
||||
if (flip)
|
||||
product = theunit->denominator;
|
||||
else
|
||||
product = theunit->numerator;
|
||||
|
||||
for (; *product; product++) {
|
||||
|
||||
for (;;) {
|
||||
if (!strlen(*product))
|
||||
break;
|
||||
toadd = lookupunit(*product);
|
||||
if (!toadd) {
|
||||
mywarnx("Unknown unit '%s'", *product);
|
||||
return ERROR;
|
||||
}
|
||||
if (strchr(toadd, PRIMITIVECHAR))
|
||||
break;
|
||||
didsomething = 1;
|
||||
if (*product != NULLUNIT) {
|
||||
free(__UNCONST(*product));
|
||||
*product = NULLUNIT;
|
||||
}
|
||||
if (addunit(theunit, toadd, flip))
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
return didsomething;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Reduces numerator and denominator of the specified unit.
|
||||
Returns 0 on success, or 1 on unknown unit error.
|
||||
*/
|
||||
|
||||
static int
|
||||
reduceunit(struct unittype * theunit)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = 1;
|
||||
while (ret & 1) {
|
||||
ret = reduceproduct(theunit, 0) | reduceproduct(theunit, 1);
|
||||
if (ret & 4)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
compareproducts(const char **one, const char **two)
|
||||
{
|
||||
while (*one || *two) {
|
||||
if (!*one && *two != NULLUNIT)
|
||||
return 1;
|
||||
if (!*two && *one != NULLUNIT)
|
||||
return 1;
|
||||
if (*one == NULLUNIT)
|
||||
one++;
|
||||
else if (*two == NULLUNIT)
|
||||
two++;
|
||||
else if (*one && *two && strcmp(*one, *two))
|
||||
return 1;
|
||||
else
|
||||
one++, two++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return zero if units are compatible, nonzero otherwise */
|
||||
|
||||
static int
|
||||
compareunits(struct unittype * first, struct unittype * second)
|
||||
{
|
||||
return
|
||||
compareproducts(first->numerator, second->numerator) ||
|
||||
compareproducts(first->denominator, second->denominator);
|
||||
}
|
||||
|
||||
static int
|
||||
compareunitsreciprocal(struct unittype * first, struct unittype * second)
|
||||
{
|
||||
return
|
||||
compareproducts(first->numerator, second->denominator) ||
|
||||
compareproducts(first->denominator, second->numerator);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
completereduce(struct unittype * unit)
|
||||
{
|
||||
if (reduceunit(unit))
|
||||
return 1;
|
||||
sortunit(unit);
|
||||
cancelunit(unit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
showanswer(struct unittype * have, struct unittype * want)
|
||||
{
|
||||
if (compareunits(have, want)) {
|
||||
if (compareunitsreciprocal(have, want)) {
|
||||
printf("conformability error\n");
|
||||
showunit(have);
|
||||
showunit(want);
|
||||
} else {
|
||||
printf("\treciprocal conversion\n");
|
||||
printf("\t* %.*g\n\t/ %.*g\n",
|
||||
precision, 1 / (have->factor * want->factor),
|
||||
precision, want->factor * have->factor);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("\t* %.*g\n\t/ %.*g\n",
|
||||
precision, have->factor / want->factor,
|
||||
precision, want->factor / have->factor);
|
||||
}
|
||||
|
||||
static int
|
||||
listunits(int expand)
|
||||
{
|
||||
struct unittype theunit;
|
||||
const char *thename;
|
||||
const char *thedefn;
|
||||
int errors = 0;
|
||||
int i;
|
||||
int printexpansion;
|
||||
|
||||
/*
|
||||
* send error and warning messages to stdout,
|
||||
* and make them look like comments.
|
||||
*/
|
||||
errprefix = "/ ";
|
||||
|
||||
#if 0 /* debug */
|
||||
printf("/ expand=%d precision=%d unitcount=%d prefixcount=%d\n",
|
||||
expand, precision, unitcount, prefixcount);
|
||||
#endif
|
||||
|
||||
/* 1. Dump all primitive units, e.g. "m !a!", "kg !b!", ... */
|
||||
printf("/ Primitive units\n");
|
||||
for (i = 0; i < unitcount; i++) {
|
||||
thename = unittable[i].uname;
|
||||
thedefn = unittable[i].uval;
|
||||
if (thedefn[0] == PRIMITIVECHAR) {
|
||||
printf("%s\t%s\n", thename, thedefn);
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. Dump all prefixes, e.g. "yotta- 1e24", "zetta- 1e21", ... */
|
||||
printf("/ Prefixes\n");
|
||||
for (i = 0; i < prefixcount; i++) {
|
||||
printexpansion = expand;
|
||||
thename = prefixtable[i].prefixname;
|
||||
thedefn = prefixtable[i].prefixval;
|
||||
if (expand) {
|
||||
/*
|
||||
* prefix names are sometimes identical to unit
|
||||
* names, so we have to expand thedefn instead of
|
||||
* expanding thename.
|
||||
*/
|
||||
initializeunit(&theunit);
|
||||
if (addunit(&theunit, thedefn, 0) != 0
|
||||
|| completereduce(&theunit) != 0) {
|
||||
errors++;
|
||||
printexpansion = 0;
|
||||
mywarnx("Error in prefix '%s-'", thename);
|
||||
}
|
||||
}
|
||||
if (printexpansion) {
|
||||
printf("%s-", thename);
|
||||
showunit(&theunit);
|
||||
} else
|
||||
printf("%s-\t%s\n", thename, thedefn);
|
||||
}
|
||||
|
||||
/* 3. Dump all other units. */
|
||||
printf("/ Other units\n");
|
||||
for (i = 0; i < unitcount; i++) {
|
||||
printexpansion = expand;
|
||||
thename = unittable[i].uname;
|
||||
thedefn = unittable[i].uval;
|
||||
if (thedefn[0] == PRIMITIVECHAR)
|
||||
continue;
|
||||
if (expand) {
|
||||
/*
|
||||
* expand thename, not thedefn, so that
|
||||
* we can catch errors in the name itself.
|
||||
* e.g. a name that contains a hyphen
|
||||
* will be interpreted as multiplication.
|
||||
*/
|
||||
initializeunit(&theunit);
|
||||
if (addunit(&theunit, thename, 0) != 0
|
||||
|| completereduce(&theunit) != 0) {
|
||||
errors++;
|
||||
printexpansion = 0;
|
||||
mywarnx("Error in unit '%s'", thename);
|
||||
}
|
||||
}
|
||||
if (printexpansion) {
|
||||
printf("%s", thename);
|
||||
showunit(&theunit);
|
||||
} else
|
||||
printf("%s\t%s\n", thename, thedefn);
|
||||
}
|
||||
|
||||
if (errors)
|
||||
mywarnx("Definitions with errors: %d", errors);
|
||||
return (errors ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"\nunits [-Llqv] [-f filename] [[count] from-unit to-unit]\n");
|
||||
fprintf(stderr, "\n -f specify units file\n");
|
||||
fprintf(stderr, " -L list units in standardized base units\n");
|
||||
fprintf(stderr, " -l list units\n");
|
||||
fprintf(stderr, " -q suppress prompting (quiet)\n");
|
||||
fprintf(stderr, " -v print version number\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
||||
struct unittype have, want;
|
||||
char havestr[81], wantstr[81];
|
||||
int optchar;
|
||||
const char *userfile = 0;
|
||||
int list = 0, listexpand = 0;
|
||||
int quiet = 0;
|
||||
|
||||
while ((optchar = getopt(argc, argv, "lLvqf:")) != -1) {
|
||||
switch (optchar) {
|
||||
case 'l':
|
||||
list = 1;
|
||||
break;
|
||||
case 'L':
|
||||
list = 1;
|
||||
listexpand = 1;
|
||||
precision = DBL_DIG;
|
||||
break;
|
||||
case 'f':
|
||||
userfile = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
case 'v':
|
||||
fprintf(stderr, "\n units version %s Copyright (c) 1993 by Adrian Mariano\n",
|
||||
VERSION);
|
||||
fprintf(stderr, " This program may be freely distributed\n");
|
||||
usage();
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if ((argc != 3 && argc != 2 && argc != 0)
|
||||
|| (list && argc != 0))
|
||||
usage();
|
||||
|
||||
if (list)
|
||||
errprefix = "/ "; /* set this before reading the file */
|
||||
|
||||
readunits(userfile);
|
||||
|
||||
if (list)
|
||||
return listunits(listexpand);
|
||||
|
||||
if (argc == 3) {
|
||||
strlcpy(havestr, argv[0], sizeof(havestr));
|
||||
strlcat(havestr, " ", sizeof(havestr));
|
||||
strlcat(havestr, argv[1], sizeof(havestr));
|
||||
argc--;
|
||||
argv++;
|
||||
argv[0] = havestr;
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
strlcpy(havestr, argv[0], sizeof(havestr));
|
||||
strlcpy(wantstr, argv[1], sizeof(wantstr));
|
||||
initializeunit(&have);
|
||||
addunit(&have, havestr, 0);
|
||||
completereduce(&have);
|
||||
initializeunit(&want);
|
||||
addunit(&want, wantstr, 0);
|
||||
completereduce(&want);
|
||||
showanswer(&have, &want);
|
||||
}
|
||||
else {
|
||||
if (!quiet)
|
||||
printf("%d units, %d prefixes\n\n", unitcount,
|
||||
prefixcount);
|
||||
for (;;) {
|
||||
do {
|
||||
initializeunit(&have);
|
||||
if (!quiet)
|
||||
printf("You have: ");
|
||||
if (!fgets(havestr, 80, stdin)) {
|
||||
if (!quiet)
|
||||
putchar('\n');
|
||||
exit(0);
|
||||
}
|
||||
} while (addunit(&have, havestr, 0) ||
|
||||
completereduce(&have));
|
||||
do {
|
||||
initializeunit(&want);
|
||||
if (!quiet)
|
||||
printf("You want: ");
|
||||
if (!fgets(wantstr, 80, stdin)) {
|
||||
if (!quiet)
|
||||
putchar('\n');
|
||||
exit(0);
|
||||
}
|
||||
} while (addunit(&want, wantstr, 0) ||
|
||||
completereduce(&want));
|
||||
showanswer(&have, &want);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
651
usr.bin/units/units.lib
Normal file
651
usr.bin/units/units.lib
Normal file
|
@ -0,0 +1,651 @@
|
|||
/ $NetBSD: units.lib,v 1.17 2012/12/28 17:57:46 apb Exp $
|
||||
|
||||
/ primitive units
|
||||
|
||||
m !a!
|
||||
kg !b!
|
||||
sec !c!
|
||||
coul !d!
|
||||
candela !e!
|
||||
dollar !f!
|
||||
bit !h!
|
||||
erlang !i!
|
||||
K !j!
|
||||
|
||||
/ prefixes
|
||||
|
||||
yotta- 1e24
|
||||
zetta- 1e21
|
||||
exa- 1e18
|
||||
peta- 1e15
|
||||
tera- 1e12
|
||||
giga- 1e9
|
||||
mega- 1e6
|
||||
myria- 1e4
|
||||
kilo- 1e3
|
||||
hecto- 1e2
|
||||
deka- 1e1
|
||||
deci- 1e-1
|
||||
centi- 1e-2
|
||||
milli- 1e-3
|
||||
micro- 1e-6
|
||||
nano- 1e-9
|
||||
pico- 1e-12
|
||||
femto- 1e-15
|
||||
atto- 1e-18
|
||||
zopto- 1e-21
|
||||
yocto- 1e-24
|
||||
|
||||
semi- .5
|
||||
demi- .5
|
||||
|
||||
Y- yotta
|
||||
Z- zetta
|
||||
E- exa
|
||||
P- peta
|
||||
T- tera
|
||||
G- giga
|
||||
M- mega
|
||||
k- kilo
|
||||
h- hecto
|
||||
da- deka
|
||||
d- deci
|
||||
c- centi
|
||||
m- milli
|
||||
p- pico
|
||||
f- femto
|
||||
a- atto
|
||||
z- zopto
|
||||
y- yocto
|
||||
|
||||
/ constants
|
||||
|
||||
fuzz 1
|
||||
pi 3.14159265358979323846
|
||||
c 2.99792458e+8 m/sec fuzz
|
||||
g 9.80665 m/sec2
|
||||
au 1.49597871e+11 m fuzz
|
||||
mole 6.022169e+23 fuzz
|
||||
e 1.6021917e-19 coul fuzz
|
||||
energy c2
|
||||
force g
|
||||
mercury 1.33322e+5 kg/m2-sec2
|
||||
hg mercury
|
||||
|
||||
/ dimensionless
|
||||
|
||||
radian .5 / pi
|
||||
degree 1|180 pi-radian
|
||||
circle 2 pi-radian
|
||||
turn 2 pi-radian
|
||||
revolution turn
|
||||
rev turn
|
||||
grade .9 degree
|
||||
arcdeg 1 degree
|
||||
arcmin 1|60 arcdeg
|
||||
ccs 1|36 erlang
|
||||
arcsec 1|60 arcmin
|
||||
|
||||
steradian radian2
|
||||
sphere 4 pi-steradian
|
||||
sr steradian
|
||||
|
||||
/ Time
|
||||
|
||||
second sec
|
||||
s sec
|
||||
minute 60 sec
|
||||
min minute
|
||||
hour 60 min
|
||||
hr hour
|
||||
day 24 hr
|
||||
da day
|
||||
week 7 day
|
||||
year 365.24219879 day fuzz
|
||||
yr year
|
||||
month 1|12 year
|
||||
ms millisec
|
||||
us microsec
|
||||
|
||||
/ Mass
|
||||
|
||||
gram millikg
|
||||
gm gram
|
||||
mg milligram
|
||||
metricton kilokg
|
||||
|
||||
/ Avoirdupois
|
||||
|
||||
lb .45359237 kg
|
||||
pound lb
|
||||
lbf lb g
|
||||
ounce 1|16 lb
|
||||
oz ounce
|
||||
dram 1|16 oz
|
||||
dr dram
|
||||
grain 1|7000 lb
|
||||
gr grain
|
||||
shortton 2000 lb
|
||||
ton shortton
|
||||
longton 2240 lb
|
||||
|
||||
/ Apothecary
|
||||
|
||||
scruple 20 grain
|
||||
apdram 60 grain
|
||||
apounce 480 grain
|
||||
appound 5760 grain
|
||||
troypound appound
|
||||
|
||||
/ Length
|
||||
|
||||
meter m
|
||||
cm centimeter
|
||||
mm millimeter
|
||||
km kilometer
|
||||
nm nanometer
|
||||
micron micrometer
|
||||
angstrom decinanometer
|
||||
|
||||
inch 2.54 cm
|
||||
in inch
|
||||
foot 12 in
|
||||
feet foot
|
||||
ft foot
|
||||
yard 3 ft
|
||||
yd yard
|
||||
rod 5.5 yd
|
||||
rd rod
|
||||
mile 5280 ft
|
||||
mi mile
|
||||
|
||||
british 1200|3937 m/ft
|
||||
nmile 1852 m
|
||||
|
||||
acre 4840 yd2
|
||||
|
||||
cc cm3
|
||||
liter kilocc
|
||||
ml milliliter
|
||||
|
||||
/ US Liquid
|
||||
|
||||
gallon 231 in3
|
||||
imperial 1.20095
|
||||
gal gallon
|
||||
quart 1|4 gal
|
||||
qt quart
|
||||
pint 1|2 qt
|
||||
pt pint
|
||||
|
||||
floz 1|16 pt
|
||||
fldr 1|8 floz
|
||||
|
||||
/ US Dry
|
||||
|
||||
dry 268.8025 in3/gallon fuzz
|
||||
peck 8 dry-quart
|
||||
pk peck
|
||||
bushel 4 peck
|
||||
bu bushel
|
||||
chaldron 36 bushel
|
||||
|
||||
/ British
|
||||
|
||||
brgallon 277.420 in3 fuzz
|
||||
brquart 1|4 brgallon
|
||||
brpint 1|2 brquart
|
||||
brfloz 1|20 brpint
|
||||
brpeck 554.84 in3 fuzz
|
||||
brbushel 4 brpeck
|
||||
|
||||
/ Bottles
|
||||
|
||||
bottle 750 milliliter
|
||||
/bottle fifth
|
||||
|
||||
miniature 100 milliliter
|
||||
split 1|4 bottle
|
||||
half 1|2 bottle
|
||||
magnum 2 bottle
|
||||
jeroboam 4 bottle
|
||||
rehoboam 6 bottle
|
||||
methuselah 8 bottle
|
||||
salmanazar 12 bottle
|
||||
balthazar 16 bottle
|
||||
nebuchadnezzar 20 bottle
|
||||
sovereign 34 bottle
|
||||
|
||||
/ Bottles - alternate names and spellings
|
||||
|
||||
pony split
|
||||
fillette half
|
||||
tappithen 3 bottle
|
||||
rheoboam rehoboam
|
||||
shalmaneser salmanazar
|
||||
|
||||
/ Energy Work
|
||||
|
||||
newton kg-m/sec2
|
||||
nt newton
|
||||
N newton
|
||||
joule nt-m
|
||||
cal 4.1868 joule
|
||||
|
||||
/ Electrical
|
||||
|
||||
coulomb coul
|
||||
C coul
|
||||
ampere coul/sec
|
||||
amp ampere
|
||||
watt joule/sec
|
||||
volt watt/amp
|
||||
ohm volt/amp
|
||||
mho /ohm
|
||||
farad coul/volt
|
||||
henry sec2/farad
|
||||
weber volt-sec
|
||||
|
||||
/ Light
|
||||
|
||||
cd candela
|
||||
lumen cd sr
|
||||
lux cd sr/m2
|
||||
|
||||
/ Wall Street Journal, July 2, 1993
|
||||
|
||||
$ dollar
|
||||
argentinapeso $
|
||||
australiadollar .66 $
|
||||
bahraindinar 2.6522 $
|
||||
brazilcruzeiro .000019 $
|
||||
britainpound 1.49 $
|
||||
canadadollar .77 $
|
||||
czechkoruna .034 $
|
||||
chilepeso .0025 $
|
||||
chinarenminbi .174856 $
|
||||
colombiapeso .001495 $
|
||||
denmarkkrone .15 $
|
||||
ecuadorsucre .000539 $
|
||||
europeeuro 0.9142 $
|
||||
greatbritainpound britainpound
|
||||
hongkongdollar .13 $
|
||||
hungaryforint .011 $
|
||||
indiarupee .03211 $
|
||||
indonesiarupiah .0004782 $
|
||||
israelshekel .3642 $
|
||||
japanyen .0093 $
|
||||
jordandinar 1.4682 $
|
||||
kuwaitdinar 3.3173 $
|
||||
lebanonpound .000578 $
|
||||
malaysiaringgit .338 $
|
||||
maltalira 2.6042 $
|
||||
mexicopeso .3205128 $
|
||||
newzealanddollar .539 $
|
||||
norwaykrone .139 $
|
||||
pakistanrupee .037 $
|
||||
perunewsol .5065 $
|
||||
philippinespeso .03738 $
|
||||
polandzloty .000059 $
|
||||
saudiarabiariyal .26702 $
|
||||
singaporedollar .6157 $
|
||||
slovakkoruna .034 $
|
||||
southafricarand .21 $
|
||||
southkoreawon .001 $
|
||||
swedenkrona .13 $
|
||||
switzerlandfranc .66 $
|
||||
taiwandollar .038285 $
|
||||
thailandbaht .03962 $
|
||||
turkeylira .0000929 $
|
||||
unitedarabdirham .2723 $
|
||||
uruguaynewpeso .246852 $
|
||||
venezuelabolivar .011 $
|
||||
|
||||
/ The following currencies are locked to the Euro:
|
||||
/ <URL:http://www.ecb.int/change/conversion.htm>
|
||||
belgiumfranc 1|40.3399 euro
|
||||
germanymark 1|1.95583 euro
|
||||
spainpeseta 1|166.386 euro
|
||||
francefranc 1|6.55957 euro
|
||||
irelandpunt 1|.787564 euro
|
||||
italylira 1|1936.27 euro
|
||||
luxembourgfranc 1|40.3399 euro
|
||||
netherlandsguilder 1|2.20371 euro
|
||||
austriaschilling 1|13.7603 euro
|
||||
portugalescudo 1|200.482 euro
|
||||
finlandmarkka 1|5.94573 euro
|
||||
greecedrachma 1|340.750 euro
|
||||
|
||||
mark germanymark
|
||||
euro europeeuro
|
||||
bolivar venezuelabolivar
|
||||
peseta spainpeseta
|
||||
rand southafricarand
|
||||
escudo portugalescudo
|
||||
newsol perunewsol
|
||||
guilder netherlandsguilder
|
||||
hollandguilder netherlandsguilder
|
||||
peso mexicopeso
|
||||
yen japanyen
|
||||
lira italylira
|
||||
rupee indiarupee
|
||||
drachma greecedrachma
|
||||
franc francefranc
|
||||
markka finlandmarkka
|
||||
sucre ecuadorsucre
|
||||
poundsterling britainpound
|
||||
cruzeiro brazilcruzeiro
|
||||
|
||||
/ computer
|
||||
|
||||
baud bit/sec
|
||||
byte 8 bit
|
||||
block 512 byte
|
||||
kbyte 1024 byte
|
||||
megabyte 1024 kbyte
|
||||
gigabyte 1024 megabyte
|
||||
meg megabyte
|
||||
|
||||
|
||||
/ Trivia
|
||||
|
||||
% 1|100
|
||||
admiraltyknot 6080 ft/hr
|
||||
apostilb cd/pi-m2
|
||||
are 1e+2 m2
|
||||
arpentcan 27.52 mi
|
||||
arpentlin 191.835 ft
|
||||
astronomicalunit au
|
||||
atmosphere 1.01325e+5 nt/m2
|
||||
atm atmosphere
|
||||
atomicmassunit 1.66044e-27 kg fuzz
|
||||
amu atomicmassunit
|
||||
bag 94 lb
|
||||
bakersdozen 13
|
||||
bar 1e+5 nt/m2
|
||||
barie 1e-1 nt/m2
|
||||
barleycorn 1|3 in
|
||||
barn 1e-28 m2
|
||||
barrel 42 gal
|
||||
barye 1e-1 nt/m2
|
||||
bev 1e+9 e-volt
|
||||
biot 10 amp
|
||||
blondel cd/pi-m2
|
||||
boardfoot 144 in3
|
||||
bolt 40 yd
|
||||
bottommeasure 1|40 in
|
||||
britishthermalunit 1.05506e+3 joule fuzz
|
||||
btu britishthermalunit
|
||||
refrigeration 12000 btu/ton-hour
|
||||
buck dollar
|
||||
Ci curie
|
||||
cable 720 ft
|
||||
caliber 1e-2 in
|
||||
calorie cal
|
||||
carat 205 mg
|
||||
caratgold 1|24
|
||||
cent centidollar
|
||||
cental 100 lb
|
||||
centesimalminute 1e-2 grade
|
||||
centesimalsecond 1e-4 grade
|
||||
century 100 year
|
||||
cfs ft3/sec
|
||||
chain 66 ft
|
||||
circularinch 1|4 pi-in2
|
||||
circularmil 1e-6|4 pi-in2
|
||||
clusec 1e-8 mm-hg m3/s
|
||||
coomb 4 bu
|
||||
cord 128 ft3
|
||||
cordfoot cord
|
||||
crith 9.06e-2 gm
|
||||
cubit 18 in
|
||||
cup 1|2 pt
|
||||
curie 3.7e+10 /sec
|
||||
dalton amu
|
||||
decade 10 yr
|
||||
diopter /m
|
||||
displacementton 35 ft3
|
||||
doppelzentner 100 kg
|
||||
dozen 12
|
||||
drop .03 cm3
|
||||
dyne cm-gm/sec2
|
||||
electronvolt e-volt
|
||||
ell 45 in
|
||||
engineerschain 100 ft
|
||||
engineerslink 100|100 ft
|
||||
equivalentfootcandle lumen/pi-ft2
|
||||
equivalentlux lumen/pi-m2
|
||||
equivalentphot cd/pi-cm2
|
||||
erg cm2-gm/sec2
|
||||
ev e-volt
|
||||
faraday 9.652e+4 coul
|
||||
fathom 6 ft
|
||||
fermi 1e-15 m
|
||||
fifth 4|5 qt
|
||||
fin 5 dollar
|
||||
finger 7|8 in
|
||||
firkin 9 gal
|
||||
footcandle lumen/ft2
|
||||
footlambert cd/pi-ft2
|
||||
fortnight 14 da
|
||||
franklin 3.33564e-10 coul
|
||||
frigorie kilocal
|
||||
furlong 220 yd
|
||||
Gy gray
|
||||
galileo 1e-2 m/sec2
|
||||
gamma 1e-9 weber/m2
|
||||
gauss 1e-4 weber/m2
|
||||
geodeticfoot british-ft
|
||||
geographicalmile 1852 m
|
||||
gilbert 7.95775e-1 amp
|
||||
gill 1|4 pt
|
||||
gray joule/kg
|
||||
gross 144
|
||||
gunterschain 22 yd
|
||||
hand 4 in
|
||||
hectare 1e+4 m2
|
||||
hefnercandle .92 cd
|
||||
hertz /sec
|
||||
Hz hertz
|
||||
hogshead 63 gallon
|
||||
hd hogshead
|
||||
homestead 1|4 mi2
|
||||
horsepower 550 ft-lb-g/sec
|
||||
hp horsepower
|
||||
hyl gm force sec2/m
|
||||
hz /sec
|
||||
imaginarycubicfoot 1.4 ft3
|
||||
karat 1|24
|
||||
kcal kilocal
|
||||
kcalorie kilocal
|
||||
kev 1e+3 e-volt
|
||||
key kg
|
||||
khz 1e+3 /sec
|
||||
kilderkin 18 gal
|
||||
knot nmile/hr
|
||||
lambert cd/pi-cm2
|
||||
langley cal/cm2
|
||||
last 80 bu
|
||||
league 3 mi
|
||||
lightyear c-yr
|
||||
line 1|12 in
|
||||
link 66|100 ft
|
||||
longhundredweight 112 lb
|
||||
longquarter 28 lb
|
||||
lusec 1e-6 mm-hg m3/s
|
||||
mach 331.46 m/sec
|
||||
marineleague 3 nmile
|
||||
maxwell 1e-8 weber
|
||||
metriccarat 200 mg
|
||||
mgd megagal/day
|
||||
mh millihenry
|
||||
mhz 1e+6 /sec
|
||||
mil 1e-3 in
|
||||
millennium 1000 year
|
||||
minersinch 1.5 ft3/min
|
||||
minim 1|60 fldr
|
||||
mo month
|
||||
mpg mile/gal
|
||||
mph mile/hr
|
||||
nail 1|16 yd
|
||||
nauticalmile nmile
|
||||
nit cd/m2
|
||||
noggin 1|8 qt
|
||||
nox 1e-3 lux
|
||||
ns nanosec
|
||||
oersted 2.5e+2 pi-amp/m
|
||||
oe oersted
|
||||
pace 36 in
|
||||
palm 3 in
|
||||
parasang 3.5 mi
|
||||
parsec au-radian/arcsec
|
||||
pascal nt/m2
|
||||
pc parsec
|
||||
pennyweight 1|20 oz
|
||||
pwt pennyweight
|
||||
percent %
|
||||
perch rd
|
||||
pf picofarad
|
||||
phot lumen/cm2
|
||||
pica 1|6 in
|
||||
pieze 1e+3 nt/m2
|
||||
pipe 4 barrel
|
||||
point 1|72 in
|
||||
poise gm/cm-sec
|
||||
pole rd
|
||||
poundal ft-lb/sec2
|
||||
pdl poundal
|
||||
proof 1|200
|
||||
psi lb-g/in2
|
||||
quarter 9 in
|
||||
quartersection 1|4 mi2
|
||||
quintal 100 kg
|
||||
quire 25
|
||||
R roentgen
|
||||
rackunit 1.75 in
|
||||
rad 100 erg/gm
|
||||
ream 500
|
||||
registerton 100 ft3
|
||||
rem 1e-2 sievert
|
||||
rhe 10 m2/nt-sec
|
||||
roentgen 2.58e-4 coulomb/kg
|
||||
rontgen roentgen
|
||||
rood 1.21e+3 yd
|
||||
rope 20 ft
|
||||
RU rackunit
|
||||
rutherford 1e+6 /sec
|
||||
rydberg 1.36054e+1 ev
|
||||
Sv sievert
|
||||
sabin 1 ft2
|
||||
sack 3 bu
|
||||
score 20
|
||||
seam 8 bu
|
||||
section mi2
|
||||
shed 1e-24 barn
|
||||
shippington 40 ft3
|
||||
shorthundredweight 100 lb
|
||||
shortquarter 25 lb
|
||||
siemens /ohm
|
||||
sievert joule/kg
|
||||
sigma microsec
|
||||
skein 120 yd
|
||||
skot 1e-3 apostilb
|
||||
slug lb-g-sec2/ft
|
||||
smoot 67 in
|
||||
span 9 in
|
||||
spat 4 pi sr
|
||||
spindle 14400 yd
|
||||
square 100 ft2
|
||||
stere m3
|
||||
sthene 1e+3 nt
|
||||
stilb cd/cm2
|
||||
stoke 1e-4 m2/sec
|
||||
stone 14 lb
|
||||
strike 2 bu
|
||||
surveyfoot british-ft
|
||||
surveyyard 3 surveyfoot
|
||||
surveyorschain 66 ft
|
||||
surveyorslink 66|100 ft
|
||||
tablespoon 4 fldr
|
||||
teaspoon 4|3 fldr
|
||||
tesla weber/m2
|
||||
therm 1e+5 btu
|
||||
thermie 1e+6 cal
|
||||
timberfoot ft3
|
||||
tnt 4.6e+6 m2/sec2
|
||||
tonne 1e+6 gm
|
||||
torr mm hg
|
||||
township 36 mi2
|
||||
tun 8 barrel
|
||||
U rackunit
|
||||
water gram g / cc
|
||||
wey 40 bu
|
||||
weymass 252 lb
|
||||
Xunit 1.00202e-13 m
|
||||
k 1.38047e-16 erg/degC
|
||||
|
||||
|
||||
degC K
|
||||
kelvin K
|
||||
brewster 1e-12 m2/newton
|
||||
degF 5|9 degC
|
||||
degreesrankine degF
|
||||
degrankine degreesrankine
|
||||
degreerankine degF
|
||||
degreaumur 10|8 degC
|
||||
drachm 60 grain
|
||||
poncelet 100 kg m g / sec
|
||||
denier .05|450 gram / m
|
||||
tex .001 gram / m
|
||||
englishell 45 inch
|
||||
scottishell 37.2 inch
|
||||
flemishell 27 inch
|
||||
planck 6.626e-34 joule-sec
|
||||
hbar 1.055e-34 joule-sec
|
||||
electronmass 9.1095e-31 kg
|
||||
protonmass 1.6726e-27 kg
|
||||
neutronmass 1.6606e-27 kg
|
||||
V volt
|
||||
eV e V
|
||||
bohrradius hbar2-C2/8.988e9 N m2-e2-electronmass
|
||||
becquerel 1|3.7e10 curie
|
||||
fresnel 1e12 hertz
|
||||
statcoul 1|2.99792458e9 coul
|
||||
statamp 1|2.99792458e9 amp
|
||||
statvolt 2.99792458e2 volt
|
||||
statcoulomb statcoul
|
||||
statampere statamp
|
||||
debye 3.336e-30 coul-m
|
||||
pulsatance 2 pi/sec
|
||||
rpm rev/minute
|
||||
rps rev/sec
|
||||
kilohm kiloohm
|
||||
megohm megaohm
|
||||
siderealyear 365.256360417 day
|
||||
siderealday 23.934469444 hour
|
||||
siderealhour 1|24 siderealday
|
||||
lunarmonth 29.5305555 day
|
||||
synodicmonth lunarmonth
|
||||
siderealmonth 27.32152777 day
|
||||
tropicalyear year
|
||||
solaryear year
|
||||
lunaryear 12 lunarmonth
|
||||
cran 37.5 brgallon
|
||||
kip 1000 lbf
|
||||
frenchfoot 16|15 ft
|
||||
frenchfeet frenchfoot
|
||||
toise 6 frenchfeet
|
||||
candle 1.02 candela
|
||||
militarypace 2.5 feet
|
||||
metre meter
|
||||
litre liter
|
||||
gramme gram
|
||||
iudiptheria 62.8 microgram
|
||||
iupenicillin .6 microgram
|
||||
iuinsulin 41.67 microgram
|
||||
cottonyarncount 2520 ft/pound
|
||||
linenyarncount 900 ft/pound
|
||||
worstedyarncount 1680 ft/pound
|
||||
metricyarncount meter/gram
|
||||
jewlerspoint 2 milligram
|
||||
|
Loading…
Reference in a new issue