New Numeric Types
Introduction: Kinds of Numeric Types
Kinds of New Numeric Types
- Possible kinds of numeric types:
- Integer
- Floating point
- Fixed point
- Modular
A Type is Characterized by ...
- A set of values and
- A set of operations
- Example Integer (from package Standard):
- Values: Integer'first .. Integer'last
- Operations:
- Declare: x: Integer;
- Assign: x := 3;
- Relational and equality: x < y and y /= z
- Attributes: Integer'first, Integer.image(x),
- IO: get(x); put(x);
- What about this: put(x'img)
- Defined in Ada.Integer_Text_IO
- why Text_IO, if it's for Integer
- Be aware of operations when defining new types
New Integer Types
New Integer Type - Example
- Example: types (not subtypes) for temperature and pressure
type Temperature is Range 32 .. 212;
type Pressure is Range 0 .. 500;
t: Temperature;
p: Pressure;
r: Integer;
...
t := 100; -- valid
p := t; -- compile error
r := p + t; -- compile error
Bounds must be static expressions
- known or calculated at compile time
- Subtypes and have dynamic bounds (ie calculated at runtime)
New Integer Types - Motivation
- Primary Motivation: Reduce errors:
- Only valid values can be assigned to t and p
- Types cannot be mixed in assignemnt or expressions
- Programming at level of problem not level of machine
- In c/c++/Java, everything is an int (or a long, short, ..., char
New Integer Types - Operations
- Automatically get all operations defined for type Integer
- Arithmetic, relational, equality, declare, assign
- But, need to define I/O package
- Example: No predefined routine to print a Pressure
New Integer Types - New IO Package Required
- New types need new IO packages
- Example:
type Temperature is Range 32 .. 212;
type Pressure is Range 0 .. 500;
package Temperature_IO is new Ada.Text_IO.Integer_IO(Temperature);
package Pressure_IO is new Ada.Text_IO.Integer_IO(Pressure);
use Temperature_IO, Pressure_IO;
t: Temperature;
p: Pressure;
...
begin
get(t);
get(p);
Truth in advertising (almost): Ada.Text_IO.Integer_IO
is defined as
package Ada.Integer_Text_IO. is new Ada.Text_IO.Integer_IO(Integer);
New Integer Types - Mixing Types
- Sometimes mixed type expressions are needed and conversions must be used.
p1, p2: Pressure
t1, t2: Temperature;
old_p, new_p, increase_p: Pressure;
v: Volume;
...
new_p := old_p + increase_p; -- okay
v := Volume(Integer(t) * Integer(Pressure));
-- Conversion required
How does this help?
- Programmer is alerted of the type mismatch and forced to explicitly approve it
New Integer Types - What Does Conversion Do?
- Temperature and Pressure probably both have 32-bit Integer as underlying representation
- Conversion does not change value in any way
- Conversion signals compiler to allow computation, even though types don't match
- Could save space by using smaller representation, if desired
Examples:
- Homework_One - the blunder in the code could have been detected at compile time with appropriate use
of new types
- Tainted:
type Unsafe_String is new String(1 .. 10);
type Safe_String is new String(1 .. 10);
procedure get(u: out Unsafe_String) ...
function sanitize(u: Unsafe_String) return Safe_String ...
procedure do_something_dangerous(ss: Safe_String);
Unfinished example with tennis scoring:
tennis.adb and
prettified
New Floating Point Types
Floating Point Types
- We can declare new floating point types
- Example:
type Volume is Digits 6 Range 10.0 .. 1_000.0; -- Cubic Centimeters
type Weight is Digits 6 Range 50.0 .. 500.0; -- Grams
h: Height;
w: Weight;
density: Float;
h := 100.0; -- valid
-- w := h; -- compile error
w := 50.0;
-- Sometimes need to convert types
density := float(h) / float(w);
The digits specifier tells how many digits of precision the number will have
- So Volume values include 10.0001 to 1_000.99
- So Weight values include 50.0001 to 500.999
- Type Float and Long_Long_Float have digits 6 and 18, respectively
New Floating Point Types - IO Packages
type Volume is Digits 8 Range 10.0 .. 1_000.0; -- Cubic Centimeters
type Weight is Digits 8 Range 50.0 .. 500.0; -- Grams
package Volume_IO is new Ada.Text_IO.Float_IO(Volume);
package Weight_IO is new Ada.Text_IO.Float_IO(Weight);
use Volume_IO, Weight_IO;
Fixed Point Types
What Does Floating Point Mean?
- Fixed Point Types vs Floating Point Types
- Type Float: decimal point floats (ie it moves among the significant digits)
type Volume is Digits 6 Range 10.0 .. 1_000.0; -- Cubic Centimeters
v: Volume;
v := 10_123.0 -- 10_123.00
v := v / 10.0; -- 1_012.300
v := v / 10.0; -- 101.2300
Actually, binary point moves among binary digits
Problem: Floating point can give inexact results:
cent: Float := 0.01;
dollar: Float := 0.0;
for i in 1 .. 100 loop
dollar := dollar + cent;
end loop;
put(dollar); -- 0.9999993443
Why?
Decimal Fixed Point Types
- Solution: Decimal fixed point types have a constant, fixed number of decimal places
- Good for problems involving money
type Money is delta 0.01 digits 12;
cent: Money := 0.01;
dollar: Money := 0.0;
annualSal := 1234567.89;
put_line(annualSal'img); -- 1234567.89
annualSal := annualSal / 10; -- Division fixed by int is okay
put_line(annualSal'img); -- 123456.78 -- Truncates toward 0!
annualSal := annualSal / 10;
put_line(annualSal'img); -- 12345.67
for i in 1 .. 100 loop
dollar := dollar + cent;
end loop;
put(dollar); -- 1.00
Another example - calculate missing salary:
subtype Salary is Money digits 10;
annualSal: Salary := 100_000.00;
monthlySal: Salary := annualSal / 12; -- 8333.33
missingSal := annualSal - (12 * monthlySal); -- 0.04
- Shows number of cents that must be added to paycheck over the year
Fixed Point and Decimal Fixed Point Types
- Decimal Fixed point types are decimal based
- Ordinary Fixed point types are binary based
- Example:
subtype Volt is delta 0.125 range 0.0 .. 255.0;
- 0.125 = 2#0.001# = (0.5)**3
Modular Types
Modular Types
- Modular types:
- Values of modular types are never negative
- Modular types use modular arithmetic
- Example 1 - Hours: values range from 0 .. 11:
type Hour_t is mod 12;
Values always in 0 .. 11 (ie remainder mod 12)
All operations are mod 12
Example 1 - continued
type Hour_t is mod 12; -- values range from 0 to 11
startTime: Hour_t := 8;
breakTime: Hour_t := startTime + 4; -- 0
endTime: Hour_t := startTime + 6; -- 2
notifyTime: Hour_t := startTime - 11; -- 9
Example 2 - 32 bit unsigned value (no sign bit - useful for addresses):
type Address is mod 2**32;
Similar to C unsigned types and Java char type
New Numeric Types or Subtypes
New Type or Subtypes
- New Type Advantages
- Subype Advantages
- Easier (no conversions)
- Easier (use existing IO)
Derived Types
Derived Type - Create New Types from Existing type
type Temperature is new Integer Range 32 .. 212;
type Pressure is new Integer Range 0 .. 500;
type Volume is new Float Range 10.0 .. 1_000.0;
type Weight is new Float Range 50.0 .. 500.0;
Like new numeric types, but
- Specify the underlying type:
- Bounds can be dynamic
- Can be done with non-numeric types
- Can inherit operations from underlying
For new integer types as described above, compiler chooses the underlying type
- Compiler choosing is more portable