File Coverage

blib/lib/Data/Convert/MicrochipTechnology/Float.pm
Criterion Covered Total %
statement 28 28 100.0
branch 10 10 100.0
condition 7 15 46.6
subroutine 7 7 100.0
pod 4 4 100.0
total 56 64 87.5


line stmt bran cond sub pod time code
1             package Data::Convert::MicrochipTechnology::Float;
2 1     1   25936 use strict;
  1         2  
  1         45  
3              
4             BEGIN {
5 1     1   5 use vars qw($VERSION);
  1         2  
  1         47  
6 1     1   326 $VERSION = '0.03';
7             }
8              
9             =head1 NAME
10              
11             Data::Convert::MicrochipTechnology::Float - Converts Microchip Technology 32-bit float to a number
12              
13             =head1 SYNOPSIS
14              
15             use Data::Convert::MicrochipTechnology::Float;
16             my $object = Data::Convert::MicrochipTechnology::Float->new();
17             my $float=$obj->convert("\0\0\0\0");
18             print "Float: $float\n";
19              
20             =head1 DESCRIPTION
21              
22             The format of the PIC 32-bit float is eeeeeeee smmmmmmm mmmmmmmm mmmmmmmm (4-bytes => 8-bit biased exponent, 1-bit sign, 23-bit significand)
23              
24             The number has value v: v = s * 2**e * m
25             s = +1 (positive numbers) when the sign bit is 0
26             s = -1 (negative numbers) when the sign bit is 1
27             e = Exp - 127 (the exponent is biased with 127)
28             m = 1.fraction in binary (the significand is the binary number 1 followed by the radix point followed by the binary bits of the fraction). Therefore, 1 = m < 2.
29              
30             =head1 USAGE
31              
32             =head1 CONSTRUCTOR
33              
34             =head2 new
35              
36             my $object = Data::Convert::MicrochipTechnology::Float->new();
37              
38             =cut
39              
40             sub new {
41 1     1 1 16 my $this = shift();
42 1   33     9 my $class = ref($this) || $this;
43 1         2 my $self = {};
44 1         4 bless $self, $class;
45             #$self->initialize(@_);
46 1         4 return $self;
47             }
48              
49             =head1 METHODS
50              
51             =head2 convert
52              
53             my $float=$obj->convert("\0\0\0\0");
54             my @list=$obj->convert("\0\0\0\0", "\0\0\0\0");
55             my $listref=$obj->convert("\0\0\0\0", "\0\0\0\0");
56             my $float=$obj->convert([0,0,0,0]);
57             my @list=$obj->convert("\0\0\0\0", [0,0,0,0]);
58             my $listref=$obj->convert("\0\0\0\0", [0,0,0,0]);
59              
60             =cut
61              
62             sub convert {
63 14     14 1 7799 my $self=shift();
64 14 100       26 my @list=map {ref($_) eq 'ARRAY' ?
  18         65  
65             $self->float_from_array(@$_) :
66             $self->float_from_string($_)} @_;
67 14 100       86 return scalar(@list) == 1 ? $list[0] : (wantarray ? @list : \@list);
    100          
68             }
69              
70             =head2 float_from_string
71              
72             my $float=$obj->float_from_string("\0\0\0\0");
73              
74             =cut
75              
76             sub float_from_string {
77 15     15 1 853 my $self=shift();
78 15         17 my $string=shift();
79 15         57 return $self->float_from_array(unpack("CCCC", $string));
80             }
81              
82             =head2 float_from_array
83              
84             my $float=$obj->float_from_array(0, 0, 0, 0);
85              
86             =cut
87              
88             sub float_from_array {
89 20     20 1 26 my $self=shift();
90             #die unless 4 == scalar(@_);
91 20         31 my ($b0, $b1, $b2, $b3)=@_;
92 20 100 66     122 if (0==$b0 and (0==$b1 or 128==$b1) and 0==$b2 and 0==$b3) {
      66        
      33        
      33        
93             #eliminates rounding errors for +/- zero
94 7         29 return 0;
95             } else {
96 13 100       32 my $s = $b1 & 128 ? -1 : 1;
97 13         17 my $e = $b0 - 127;
98 13         35 my $m = 1 + ((($b1 & 127) * 256 + $b2) * 256 + $b3) / (2 ** 23);
99 13         140 my $v = $s * 2 ** $e * $m;
100 13         58 return $v;
101             }
102             }
103              
104             =head1 BUGS
105              
106             The math introduces floating point rounding errors.
107              
108             =head1 TODO
109              
110             Add a bit vector capability to eliminate any rounding errors.
111              
112             =head1 SUPPORT
113              
114             =head1 AUTHOR
115              
116             Michael R. Davis
117             CPAN ID: MRDVT
118             DavisNetworks.com
119             account=>perl,tld=>com,domain=>michaelrdavis
120             http://www.davisnetworks.com/
121              
122             =head1 COPYRIGHT
123              
124             This program is free software; you can redistribute
125             it and/or modify it under the same terms as Perl itself.
126              
127             The full text of the license can be found in the
128             LICENSE file included with this module.
129              
130             =head1 SEE ALSO
131              
132             L
133              
134             =cut
135              
136             1;