Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Болталка (https://forum.antichat.xyz/forumdisplay.php?f=46)
-   -   Перевод из дробных чисел в другие системы счисления (https://forum.antichat.xyz/showthread.php?t=143506)

Kreoda 25.09.2009 00:54

Перевод из дробных чисел в другие системы счисления
 
Такая вот лажа.Пытаюсь преобразовать дробную часть:

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.Ну,и какого... ?!

Kreoda 25.09.2009 00:59

а к какой теме тогда

Retro 25.09.2009 09:30

Перевод делается так, никаких двоек у тебя ни должно получится:

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......] и пока число не будет наиболее точным, умножай на двойку.

krypt3r 25.09.2009 11:51

Писал на перле несколько месяцев назад такой код. Выложу, может, пригодится для понимания.
Код:

#!/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;
}



Время: 01:35