Creating a Simple Conversion Family and Adding Units

From RAD Studio
Jump to: navigation, search

Go Up to Converting Measurements


One example of when you could create a new conversion family and add new measurement types might be when performing conversions between long periods of time (such as months to centuries) where a loss of precision can occur.

The cbTime family uses a day as its base unit. The base unit is the one that is used when performing all conversions within that family. Therefore, all conversions must be done in terms of days. An inaccuracy can occur when performing conversions using units of months or larger (months, years, decades, centuries, millennia) because there is not an exact conversion between days and months, days and years, and so on. Months have different lengths; years have correction factors for leap years, leap seconds, and so on.

If you are only using units of measurement greater than or equal to months, you can create a more accurate conversion family with years as its base unit. This example creates a new conversion family called cbLongTime.

Declare variables

First, you need to declare variables for the identifiers. The identifiers are used in the new LongTime conversion family, and the units of measurement that are its members:

Delphi:

var
cbLongTime: TConvFamily;
ltMonths: TConvType;
ltYears: TConvType;
ltDecades: TConvType;
ltCenturies: TConvType;
ltMillennia: TConvType;

C++:

tConvFamily cbLongTime;
TConvType ltMonths;
TConvType ltYears;
TConvType ltDecades;
TConvType ltCenturies;
TConvType ltMillennia;

Register the conversion family

Next, register the conversion family:

Delphi:

cbLongTime := RegisterConversionFamily ('Long Times');

C++:

cbLongTime = RegisterConversionFamily("Long Times");

Although an UnregisterConversionFamily procedure is provided, you do not need to unregister conversion families unless the unit that defines them is removed at run time. They are automatically cleaned up when your application shuts down.

Register measurement units

Next, you need to register the measurement units within the conversion family that you just created. You use the RegisterConversionType function, which registers units of measurement within a specified family. You need to define the base unit which in the example is years, and the other units are defined using a factor that indicates their relation to the base unit. So, the factor for ltMonths is 1/12 because the base unit for the LongTime family is years. You also include a description of the units to which you are converting.

The code to register the measurement units is shown here:

Delphi:

ltMonths := RegisterConversionType(cbLongTime,'Months',1/12);
ltYears := RegisterConversionType(cbLongTime,'Years',1);
ltDecades := RegisterConversionType(cbLongTime,'Decades',10);
ltCenturies := RegisterConversionType(cbLongTime,'Centuries',100);
ltMillennia := RegisterConversionType(cbLongTime,'Millennia',1000);

C++:

ltMonths = RegisterConversionType(cbLongTime, " Months ", 1 / 12);
ltYears = RegisterConversionType(cbLongTime, " Years ", 1);
ltDecades = RegisterConversionType(cbLongTime, " Decades ", 10);
ltCenturies = RegisterConversionType(cbLongTime, " Centuries ", 100);
ltMillennia = RegisterConversionType(cbLongTime, " Millennia ", 1000);

Use the new units

You can now use the newly registered units to perform conversions. The global Convert function can convert between any of the conversion types that you registered with the cbLongTime conversion family.

So instead of using the following Convert call,

Delphi:

Convert(StrToFloat(Edit1.Text),tuMonths,tuMillennia);

C++:

Convert(StrToFloat(Edit1->Text), tuMonths, tuMillennia);

you can now use this one for greater accuracy:

Delphi:

Convert(StrToFloat(Edit1.Text),ltMonths,ltMillennia);

C++:

Convert(StrToFloat(Edit1->Text), ltMonths, ltMillennia);

See Also