Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
sub float_conv_old { my $hex_str = shift(@_); $_ = $hex_str; my $d; # re-oder string... Alpha is "middle endian" $d .= sprintf "%0.8b%0.8b", hex($2), hex($1) while /(..)(..)/g; my @bits = split(//, $d); push(@bits, (0) x (48 - @bits)); my($s, $x, $a, $b, $c); foreach my $tuple ( [\$s, $bits[0] ], [\$x, @bits[1..8] ], [\$a, @bits[9..15] ], [\$b, @bits[16..31]], [\$c, @bits[32..47]], ) { my($var, @bits) = @$tuple; my $i = 0; foreach my $bit (reverse @bits) { $$var += $bit * 2 ** $i; $i++; } } return 0 if ($a == 0 and $b == 0 and $x == 0); my $new_x = $x - 128; #print "$a, $b, $c, ex = $x -- "; #debuging code, for when I forget how this works my $result = new Math::BigFloat my $mantissa = new Math::BigFloat 0; $mantissa += 1; $mantissa += $a * 2 ** -7; $mantissa += $b * 2 ** -23; $mantissa += $c * 2 ** -39; #print "mant = $mantissa -- "; #see above $result += $s ? -1 : 1; $result *= $mantissa; $result *= 2 ** ($x - 129); return $result; } use Inline C => <<'END_C'; #include <stdlib.h> #include <math.h> double float_conv(char * bits) { char * pEnd; int sign, exp; long long num; long long a, b; double mant; num = strtoll(bits, &pEnd, 16); a = num & 0x00ff00ff00ff; b = num & 0xff00ff00ff00; a <<= 8; b >>= 8; num = a | b; sign = num & 0x800000000000; exp = ((num & 0x7f8000000000) >> 39) - 129; mant = (double) ((num & 0x007fffffffff) | 0x008000000000); mant = (double) (mant * pow(2, exp - 39)); //return ((exp && num) ? (mant * (sign ? -1 : 1)) : 0); if (exp == -129 && num == 0) { return 0; } return (mant * (sign ? -1 : 1)); } END_C
This paste will be private.
From the Design Piracy series on my blog: