IEEE 754 Floating Point Converter
A comprehensive Dart library for IEEE 754 floating-point representation conversion supporting multiple precision formats (16-bit, 32-bit, 64-bit) and custom bit configurations. Perfect for computer organization courses, embedded systems, and educational purposes.
Table of Contents
- Features
- Installation
- Quick Start
- IEEE 754 Format Specifications
- Usage Examples
- Special Values
- Custom Formats
- API Reference
- Testing
- Contributing
- License
- Acknowledgments
Features
-
Multiple Precision Formats
- Half Precision (16-bit)
1 sign + 5 exponent + 10 fraction - Single Precision (32-bit)
1 sign + 8 exponent + 23 fraction - Double Precision (64-bit)
1 sign + 11 exponent + 52 fraction - Custom Precision
User-defined bit configurations
- Half Precision (16-bit)
-
Complete Conversion Support
- Decimal ↔ IEEE 754 binary
- Hexadecimal representation
- Octal representation
- Formatted binary output with component separation
-
Special Value Handling
- Positive/Negative Zero
- Positive/Negative Infinity
- NaN (Not a Number)
- Denormalized (Subnormal) Numbers
-
Advanced Features
- Configurable tolerance settings for precision control
- Automatic overflow/underflow detection
- Auto-accuracy mode to prevent errors
- Comprehensive exception handling
Installation
Add this to your package's pubspec.yaml file:
dependencies:
ieee754_converter: ^1.0.0
Then run:
dart pub get
Or install globally:
dart pub global activate ieee754_converter
Quick Start
import 'package:ieee754_converter/ieee754_converter.dart';
void main() {
// Convert decimal to IEEE 754 single precision
final fp = IEEE754Single.fromDecimal(12.625);
print('Binary: ${fp.binaryFormatted}');
// Output: 0 10000010 10010100000000000000000
print('Hexadecimal: ${fp.hexadecimal}');
// Output: 0x414A0000
print('Back to Decimal: ${fp.toDecimal()}');
// Output: 12.625
}
IEEE 754 Format Specifications
| Format | Total Bits | Sign | Exponent | Fraction | Bias | Max Value | Min Normalized |
|---|---|---|---|---|---|---|---|
| Half | 16 | 1 | 5 | 10 | 15 | 65,504 | 6.10 × 10⁻⁵ |
| Single | 32 | 1 | 8 | 23 | 127 | 3.40 × 10³⁸ | 1.18 × 10⁻³⁸ |
| Double | 64 | 1 | 11 | 52 | 1023 | 1.80 × 10³⁰⁸ | 2.23 × 10⁻³⁰⁸ |
Value Formula
For normalized numbers:
Value = (-1)^S × (1 + F) × 2^(E - Bias)
Where:
- S = Sign bit (0 = positive, 1 = negative)
- F = Fraction/Mantissa (stored without implicit leading 1)
- E = Biased exponent (stored value)
- Bias = Format-specific bias value
Bit Layout (Single Precision)
31 23 22 0
┌─────────────────────────────────┬─────────────────────────────────────┐
│ Sign (1 bit) │ Exponent (8 bits) │
│ (S) │ (E) │
└─────────────────────────────────┴─────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────┐
│ Fraction/Mantissa (23 bits) │
│ (F) │
└───────────────────────────────────────────────────────────────────────┘
Usage Examples
Single Precision (32-bit)
// Basic conversion
final fp = IEEE754Single.fromDecimal(12.625);
print('Sign: ${fp.sign}'); // 0
print('Exponent (biased): ${fp.exponent}'); // 130
print('Exponent (actual): ${fp.actualExponent}'); // 3
print('Fraction: ${fp.fraction}'); // 10010100000000000000000
print('Binary: ${fp.binary}'); // 01000001010010100000000000000000
print('Formatted: ${fp.binaryFormatted}'); // 0 10000010 10010100000000000000000
print('Hex: ${fp.hexadecimal}'); // 0x414A0000
print('Octal: ${fp.octal}'); // 0o041224000000
Half Precision (16-bit)
final fp = IEEE754Half.fromDecimal(12.625);
print('Binary: ${fp.binary}'); // 16-bit representation
print('Hex: ${fp.hexadecimal}'); // 0x4A50
print('Value: ${fp.toDecimal()}'); // 12.625
Double Precision (64-bit)
final fp = IEEE754Double.fromDecimal(3.141592653589793);
print('Binary: ${fp.binary}'); // 64-bit representation
print('Hex: ${fp.hexadecimal}'); // 0x400921FB54442D18
print('Value: ${fp.toDecimal()}'); // 3.141592653589793
From Binary/Hex/Octal
// From binary string
final fp1 = IEEE754Single.fromBinary('01000001010010100000000000000000');
print(fp1.toDecimal()); // 12.625
// From hexadecimal
final fp2 = IEEE754Single.fromHex('0x414A0000');
print(fp2.toDecimal()); // 12.625
// From octal
final fp3 = IEEE754Single.fromOctal('0o041224000000');
print(fp3.toDecimal()); // 12.625
Negative Numbers
final fp = IEEE754Single.fromDecimal(-12.625);
print('Sign: ${fp.sign}'); // 1
print('Binary: ${fp.binary}'); // 11000001010010100000000000000000
print('Value: ${fp.toDecimal()}'); // -12.625
Special Values
Zero
final positiveZero = IEEE754Single.fromDecimal(0.0);
print(positiveZero.specialValueType); // SpecialValueType.positiveZero
print(positiveZero.binary); // 00000000000000000000000000000000
final negativeZero = IEEE754Single.fromDecimal(-0.0);
print(negativeZero.specialValueType); // SpecialValueType.negativeZero
print(negativeZero.binary); // 10000000000000000000000000000000
Infinity
final posInf = IEEE754Single.fromDecimal(double.infinity);
print(posInf.specialValueType); // SpecialValueType.positiveInfinity
print(posInf.binary); // 01111111100000000000000000000000
final negInf = IEEE754Single.fromDecimal(double.negativeInfinity);
print(negInf.specialValueType); // SpecialValueType.negativeInfinity
print(negInf.binary); // 11111111100000000000000000000000
NaN (Not a Number)
final nan = IEEE754Single.fromDecimal(double.nan);
print(nan.specialValueType); // SpecialValueType.nan
print(nan.binary); // 01111111110000000000000000000000
Denormalized Numbers
// Very small numbers near zero
final tiny = IEEE754Single.fromDecimal(1.0e-40);
print(tiny.isSpecial); // true
print(tiny.specialValueType); // SpecialValueType.denormalized
Custom Formats
Create custom floating-point formats with user-defined bit allocations:
// Create a 24-bit custom format
final custom = IEEE754Custom(
signBits: 1,
exponentBits: 7,
fractionBits: 16,
);
print('Total bits: ${custom.totalBits}'); // 24
print('Bias: ${custom.bias}'); // 63
// Convert using custom format
final result = custom.fromDecimal(12.625);
print('Binary: ${result.binary}');
print('Value: ${result.toDecimal()}');
// Parse from binary
final parsed = custom.fromBinary('010000101001010000000000');
print('Value: ${parsed.toDecimal()}');
Custom Format Validation
// Invalid: sign bits must be 1
IEEE754Custom(signBits: 2, exponentBits: 5, fractionBits: 10);
// Throws: IEEE754InvalidFormatException
// Invalid: exponent bits must be >= 1
IEEE754Custom(signBits: 1, exponentBits: 0, fractionBits: 10);
// Throws: IEEE754InvalidFormatException
// Invalid: total bits > 128
IEEE754Custom(signBits: 1, exponentBits: 64, fractionBits: 64);
// Throws: IEEE754InvalidFormatException
Advanced Configuration
Tolerance Settings
Control precision for fraction conversion:
// Default tolerance
final fp1 = IEEE754Single.fromDecimal(0.1);
// Custom tolerance
final fp2 = IEEE754Single.fromDecimal(0.1, tolerance: 1e-7);
// Higher precision for double
final fp3 = IEEE754Double.fromDecimal(0.1, tolerance: 1e-15);
Auto-Accuracy Mode
Prevent overflow by automatically converting to infinity:
// Auto-accuracy enabled (default)
final fp1 = IEEE754Single.fromDecimal(1e40, autoAccuracy: true);
print(fp1.specialValueType); // SpecialValueType.positiveInfinity
// Auto-accuracy disabled (throws exception)
try {
final fp2 = IEEE754Single.fromDecimal(1e40, autoAccuracy: false);
} catch (e) {
print(e); // IEEE754OverflowException
}
Precision Comparison
final value = 0.1;
final half = IEEE754Half.fromDecimal(value);
final single = IEEE754Single.fromDecimal(value);
final double_ = IEEE754Double.fromDecimal(value);
print('Original: $value');
print('Half: ${half.toDecimal()} (error: ${(half.toDecimal() - value).abs()})');
print('Single: ${single.toDecimal()} (error: ${(single.toDecimal() - value).abs()})');
print('Double: ${double_.toDecimal()} (error: ${(double_.toDecimal() - value).abs()})');
API Reference
Classes
| Class | Description |
|---|---|
IEEE754Half |
16-bit half precision format |
IEEE754Single |
32-bit single precision format |
IEEE754Double |
64-bit double precision format |
IEEE754Custom |
User-defined custom format |
FloatingPointFormat |
Format configuration model |
FloatingPointResult |
Conversion result model |
BinaryUtils |
Binary conversion utilities |
Exceptions
| Exception | Description |
|---|---|
IEEE754Exception |
Base exception class |
IEEE754OverflowException |
Value exceeds representable range |
IEEE754PrecisionException |
Insufficient precision for value |
IEEE754InvalidFormatException |
Invalid bit configuration |
IEEE754ParseException |
Invalid binary/hex/octal string |
Special Value Types
| Type | Description |
|---|---|
positiveZero |
+0.0 |
negativeZero |
-0.0 |
positiveInfinity |
+∞ |
negativeInfinity |
-∞ |
nan |
Not a Number |
denormalized |
Subnormal number |
Testing
Run all tests:
dart test
Run specific test file:
dart test test/formats/ieee754_single_test.dart
Run with coverage:
dart test --coverage
Generate coverage report:
genhtml coverage/lcov.info -o coverage/html
Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/da578/ieee754_converter.git
cd ieee754_converter
# Install dependencies
dart pub get
# Run tests
dart test
# Generate documentation
dart doc
# Run analyzer
dart analyze
Code Style
This project follows the Dart style guide. Before submitting a PR:
dart format .
dart analyze
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- IEEE 754 Standard - IEEE Standard for Floating-Point Arithmetic (IEEE 754-1985, IEEE 754-2008)
- Computer Organization and Design - Patterson & Hennessy
- Computer Organization and Architecture - William Stallings
- Dart Language Team - For the excellent Dart programming language
Libraries
- ieee754_converter
- IEEE 754 Floating Point Converter Library