Такая вот лажа.Пытаюсь преобразовать дробную часть: 0.853 к примеру перевести из 10 в 2: 0.853*2 = 1.706 0.53*2 = 1.06 0.3*2 = 0.6 0.853 = 1102 должно быть.Проверяю: 0.1102 = 1*2 ^-1 + 1*2 ^-2 + 0*2 ^-3 = 0.5+0.25 = 0.75.Ну,и какого... ?!
Перевод делается так, никаких двоек у тебя ни должно получится: 0.853*2 = 1.706 - первую цифру всегда выкидываем т.е 1 0.706*2 = 1.412 - опять единичку выкидываем, оставляя только дробную часть.. 1 0.412*2 = 0.824 - оставляем ноль. 0 0.824*2=1.648 - единичку выкидываем 1 0.648*2=1.296 = 1 и т.д. Т.е получилось что-то вроде [0.110111......] и пока число не будет наиболее точным, умножай на двойку.
Писал на перле несколько месяцев назад такой код. Выложу, может, пригодится для понимания. Code: #!/usr/bin/perl use strict 'vars'; use warnings; #use diagnostics; sub check_number ($$); sub find_char ($\@); sub base_convert ($$$); sub int_convert10 ($$$); die "wrong param count\n" unless scalar @ARGV == 3; my (%qry, $int, $frac); $qry{'txt'} = shift || '72.01';#'1011101010111010'; $qry{'from'} = shift || 8; $qry{'to'} = shift || 10; $qry{'to'} =~ s/[^0-9]//g; $qry{'from'} =~ s/[^0-9]//g; if ($qry{'txt'} =~ /^(.+?)\.(.+?)$/) { ($int, $frac) = ($1, $2); #print "NUMBERS: ", $int, " ", $frac, "\n"; } else { $int = $qry{'txt'}; $frac = 0; } die "Wrong number: integer: " unless check_number $int, $qry{'from'}; if ($frac) { die "Wrong number: fraction" unless check_number $frac, $qry{'from'}; } ($int, $frac) = base_convert ($qry{'txt'}, $qry{'from'}, $qry{'to'}); print "RESULT: $int.$frac\n"; #$qry{'txt'} =~ s/[^0-9a-f]//g; exit 0; sub check_number ($$) { my ($num, $ss) = @_; my ($i, $b, @chars, $d); for $i (0 .. $ss - 1) { $chars[$i] = ($i < 10 ? $i : chr ($i + 0x57)); } $b = 1; foreach $d (split //, $num) { if (!find_char ($d, @chars) == 1) { $b = 0; last; } } return $b; } sub find_char ($\@) { my ($char, $arr) = @_; my ($elem, $b); $b = 0; foreach $elem (@$arr) { if ($char eq $elem) { $b = 1; last; } } return $b; } sub base_convert ($$$) { my ($num, $from, $to) = @_; my ($int, $frac, $res); #print $num, "\n"; if ($num =~ /^(.+?)\.(.+?)$/) { ($int, $frac) = ($1, $2); } else { $int = $num; $frac = 0; } #print $frac, "\n"; if ($from != 10) { $int = int_convert10 ($int, $from, 1) if $int; $frac = int_convert10 ($frac, $from, 0) if $frac; } print "DEC: $int $frac\n"; $int = int_convert ($int, $to, 1) if $int; $frac = int_convert ($frac, $to, 0) if $frac; return ($int, $frac); } sub int_convert10 ($$$) { my ($num, $from, $isint) = @_; my ($j, $res, $i, @digit); #print "NUM: ", $num, "\n"; @digit = split //, $num; $j = $#digit; if ($isint) { for $i (0 .. $#digit) { if ($digit[$i] =~ /^\d{1}$/) { $res += $digit[$i] * $from ** $j--; } else { $res += (ord ($digit[$i]) - 0x57) * $from ** $j--; } } } else { for $i (0 .. $#digit) { if ($digit[$i] =~ /^\d{1}$/) { $res += $digit[$i] / ($from ** ($i + 1)); #print $digit[$i], "\n"; } else { $res += (ord ($digit[$i]) - 0x57) / ($from ** ($i + 1)); } } } $res =~ s/^0\.//; #print "RES: ", $res, "\n"; return $res; } sub int_convert ($$$) { my ($num, $to, $isint) = @_; my ($ost, $res, $cnt); #print $num, "\n"; if ($isint) { while ($num > 0) { $ost = $num % $to; if ($ost < 10) { $res .= $ost; } else { $res .= chr ($ost + 0x57); } $num = int ($num / $to); } $res = join '', reverse (split //, $res); #print $res, "\n"; } else { $num = '0.' . $num; $ost = 1; $cnt = 0; #print $num, "\n"; while (($ost > 0) && ($cnt < 9)) { #print "\n=======\n", $num, "\n"; $num *= $to; #print $num, "\n"; $ost = $num - int ($num); #print $ost, "\n"; if (int ($num) < 10) { $res .= int ($num); } else { $res .= chr (int ($num) + 0x57); } #print $res, "\n"; $num = $ost; #print $num, "\n"; $cnt++; } #$res = $res; #print $res, "\n"; } return $res; }