HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML

Computing in scientific and engineering areas often deals with manipulating numbers that represent physical entities, such as durations, weights, and forces. A common source of errors in scientific computing involves processing numbers that represent different kinds of entities, or that are related to different units, and utilizing the result for additional computation. A number is referred to as dimensioned when it relates to a specific entity such as distance, time, or temperature, and the number implies a particular unit of measure. A dimensionless number, also known as a nondimensional parameter, is a ratio of physical properties and conditions of such a nature that the resulting number has no defining unit of weight, duration, and so on.

There have been several attempts to add support for handling dimensioned numbers to programming languages. The goal was to ease programming and to make it less error prone. The concerns of scientists and engineers have apparently not been noticed by programming language developers, since we don't see support for dimensioned numbers built in to many programming languages. This is unfortunate not only for scientific computing, but also for object-oriented business and financial programming, which could also benefit from compiler and language-level dimensioned number support.

This article presents a simple proposal for supporting dimensioned numbers in Java. Application development using Java in scientific and engineering environments is not yet in the spotlight, since performance is still lagging behind other languages (Fortran, C, C++, Pascal) by an order of magnitude. This situation will improve within the next few years and Java's excellent power-complexity ratio gives it the potential to soon rank as language number one in scientific and engineering areas.

The proposed language extension involves two new keywords (dimension and unit), and an extension to the syntax of numeric types. It prevents mangling different kinds of physical entities, and it takes care of unit conversion. Conversion from and to scalar (plain numeric) values is only possible by specifying applicable units.

The extension mainly performs dimension checking at compile time; its only run-time involvement deals with unit conversion, as far as non-basic units are used. The proposal consists of four categories of language extensions, and two keywords. It uses Java support for packages. It does not use object-oriented features.

Even though Java currently lacks support for dimensioned numbers, you can already adopt a convenient programming style for dealing with units, as outlined at the end of this paper.

Base Dimensions
Some dimensions are more basic than others. There are five base dimensions in physics (that I recall):

  • distance
  • time
  • mass
  • temperature
  • electric charge
For each of these dimensions we can define a primary unit:
  • meter
  • second
  • kilogram
  • Kelvin
  • Coulomb
The dimension...unit... construct covers these base dimensions:
dimension time - unit second;
dimension distance - unit meter;
dimension mass - unit kilogram;
dimension temperature - unit Kelvin;
dimension electricCharge - unit Coulomb;

Internal machine representations of dimensioned variables are relative to the base units.

Derived Dimensions
Using the base dimensions, others may be expressed through multiplication and division, e.g.,

  • speed equals distance divided by time
  • acceleration equals speed divided by time
  • impulse equals mass times speed
  • force equals mass times acceleration
The dimension...m - =... construct covers these derived dimensions:
dimension speed - = distance - / time;
dimension acceleration - = speed - / time;
dimension impulse - = mass - * speed;
dimension force - = mass - * acceleration;

Derived Units
Units are final variables of dimension types. The ones that are not defined with the base dimensions are derived. Their definition may suggest internal representation like integers, floats or doubles, but the actual representation is adapted at compile time to the highest precision applicable in the context.

The final keyword is not needed:
mass - gram - = kilogram / 1000;
distance - kilometer - = 1000 * meter;
time - minute - = 60 * seconds;
time - hour - = 60 * minute;
time - day - = 24 * hour;

Dimensioned Numbers
The actual usage of dimensions is in dimensioned numbers. These have a type made up of a numeric type (int, float, ...) and a dimension. Actual values are made up of a combination of numeric values (0, 1, 0.1, ...) and units. As with dimensions and units, multiplication and division on dimensioned numbers yield dimensioned numbers of possibly different dimensions. The examples in Listing 1 would be accepted by the compiler.

These examples would produce a compile error, as seen in Listing 2.

Physics Package
The sample package in Listing 3 illustrates how a physics package might look once the dimension and unit keywords are added to Java.

As shown in the physics package, dimensions can be derived from other dimensions and constants could be provided for common physics values.

Finance Package
A finance package would also be an interesting way to take advantage of dimensioned number support in Java. See Listing 4 for an example.

The sample finance package shown brings up an interesting aspect of dimensioned number support in a programming language: that of non-constant units that are derived from variable dimensioned numbers.

Computing Packages
A computing package might also be of value. Such a package could greatly simplify the process of building and debugging applications which require reliable calculation of memory or disk space quantities or conversions between computer-oriented units of measure. Listing 5 shows such a package.

Other dimensions and units would also apply in the computing package, such as CPU clock speed, system and network traffic load, or end-user frustration levels, as they wait for Java applets to execute within Netscape Navigator 2.0.

Java compilers may adopt the proposed extension without major difficulty (if you disagree with this proposition, send me e-mail). However, full support will require a modification of the .class file format for the dimensioned numeric data types. This would call for a synchronized operation by all Java compiler builders and users. That can only be justified if the proposed extension has proved to be worthwhile to enough Java developers (and if Sun agrees).

Therefore experiments are needed; the proof of the pudding is in the eating. We need to try out the extension, using preliminary support by compilers and preprocessors, that does not require changes to the class format. This support would be possible in the following way:

  • the original package files are named physics.dim instead of physics.java, etc
  • the compiler or preprocessor gets a command line hint to use the appropriate .dim files, e.g., guavac -d physics.dim - d finance.dim
  • files physics.java etc. are derived from the .dim files by only selecting the constant definitions; these become all double scalars
An example for new physics.java is shown in Listing 6.

Who is going to implement these ideas? At least for the time being, not me. I am extremely busy with other projects, e.g., see http://www.delftware.nl/scriptic/. So if you are a compiler builder, or if you want to contribute to a GNU Java compiler, please go ahead and let me know.

Emulating Units in Java Today
While no compiler support is available today for dimensions and units in Java, you may use the previous physics.java file to deal with physical units in your code now. Just forget about the double*length syntax etc, but write things like the following:

double len = 1.5*kilometer;
double t = 8.3*minute;
System.out.println("Speed: " + ( (len/t) / (meter/second) ) +
" m/s");

This working style doesn't give you the full benefits of dimensional checking, but at least it will make your code more readable, and you will have less worry about units.

About the Author
Andre van Delft studied Mathematics and Business Administration in Holland. Then he joined the Department of Computer Science at Leiden University for four years. From 1989 on he has worked in Delftware Technology as consultant and software developer. His topics of interest are software engineering, reliability and parallel programming. He can be reached at [email protected]


Listing 1

double * time     t;
float  * distance d = 60 * meter;
t = 18.3 * second;
System.out.println ("speed: "
                   + ( (d/t) / (kilometer/hour))
                   +          " kilometer/hour");
double * electricTension    tension	   = 3.5 * Volt;
double * electricResistance resistance   = 1200 * Ohm;
System.out.println ("Electric current: "
                   + ( (tension/resistance)
                     / milliAmpere )
                   + "mA");

Listing 2

double * time     t;
t = 18.3; // compile error
System.out.println ("speed: " + (d/t)); // compile error

Listing 3

package physics;
interface dimensions {

// base dimensions
dimension time		unit second;
dimension distance		unit meter;
dimension mass		unit kilogram;
dimension temperature	unit Kelvin;
dimension electricCharge	unit Coulomb;

// derived dimensions
dimension speed		= distance	/ time;
dimension acceleration	= speed		/ time;
dimension impulse		= mass		* speed;
dimension force		= mass		* acceleration;
dimension torque		= force		* distance;
dimension energy		= force		* distance;
dimension power		= energy		/ time;
dimension frequency	= 1		/ time;
dimension electricCurrent	= electricCharge	/ time;
dimension electricTension	= power		/ electricCurrent;
dimension electricResistance	= electricTension / electricCharge;

// various units
mass				gram		= kilogram / 1000;
distance		kilometer		= 1000 * meter;
time				minute		= 60 * seconds;
time				hour		= 60 * minute;
time				day		= 24 * hour;
time				week		= 7 * day;
time				milliSecond	= second / 1000;
time				microSecond	= milliSecond / 1000;
time				nanoSecond	= microSecond / 1000;
frequency		Hertz		= 1 / second; 
force			Newton		= gravityAcceleration*kg;
energy		Joule		= Newton * meter;
power			Watt		= Joule / second;
electricCurrent	Ampere		= Coulomb / second;
electricCurrent	milliAmpere	= Ampere / 1000;
electricTension	Volt		= Watt / Ampere;
electricTension	milliVolt		= Volt / 1000;
electricResistance	Ohm		= Volt / Ampere;

// constants
double*speed lightspeed = 299999.97 * kilometer / second;
double*acceleration gravityAcceleration = 9.81 * meter /
package physics.shorthand;
interface dimensions extends physics.dimensions {
distance		m	= meter;
distance		km	= kilometer;
time				s	= second;
time				ms	= milliSecond;
time				us	= microSecond;
time				ns	= nanoSecond;
force			N	= Newton;
electricTension	V	= Volt;
electricTension 	mV	= Volt/1000;

Listing 4

package finance;
interface dimensions {

// base dimensions
dimension money unit usDollar;

// non-constant units: dimensioned numbers
double*money euro		= usDollar * 1.64;
double*money dutchGuilder	= usDollar / 1.59;

package finance.swift;
interface dimensions extends finance.dimensions {
double*money USD = usDollar;
double*money NLG = dutchGuilder;

Listing 5

package computing;
interface dimensions {

// base dimensions
dimension data unit byte;

// derived dimensions
data kiloByte = 1024 * byte;
data megaByte = 1024 * kiloByte;
data gigaByte = 1024 * megaByte;
data teraByte = 1024 * gigaByte;

// non-constant units

package computing.oldFashioned;
interface dimensions extends computing.dimensions {
data block = 512 * byte;

Listing 6

package physics;
interface dimensions {
final double	second		= 1.0d;
final double	meter		= 1.0d;
final double	kilogram		= 1.0d;
final double	Coulomb		= 1.0d;
final double	Kelvin		= 1.0d;
final double	gram		= 0.001d;
final double	kilometer		= 1000.0d;
final double	minute		= 60d;
final double	hour		= 60d * minute;

final double lightspeed = 299999.97d * kilometer / second;


All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.