Страница 1 из 3

написать программу вычисления двоичного представления числа

Добавлено: 20 ноя 2006, 14:20
john_1
написать программу,использующую процедуру вычисления двоичного представления числа S=0+1/5^1+1/5^2+1/5^3+...+1/5^N (n=8,10,20)
в вычисленияхудерживать 200 двоичных цифр.вывести на печаит первые 100 двоичных цифр.для организации вывода символов двоичных цифр использовать сдвиги бит

Добавлено: 20 ноя 2006, 16:29
Хыиуду
И в чем проблема? Нахождение самого числа - простой цикл for. Дальше 100 раз делать сдвиг влево (shl) и смотреть младший бит целой части. Правда, в таком случае требование о 200 удерживаемых в памяти разрядах - ни к селу ни к городу. Ну удерживаются они, толку-то, если их никто не увидит?
Второй вариант - просто по правилам переводить число в двоичный формат и записывать в строку (множить на 2, смотреть младший бит целой части). Только в таком случае никак нельзя использовать побитовый сдвиг.

Добавлено: 20 ноя 2006, 18:13
john_1
не все так просто.дело в том что если просто сложить это число(получить сумму),то оно будет не точное(округлиться).в этом вся и загвоздка надо каким-нить образом запихать его в массив а от туда переводить!!!!!!!!!!а вот как?

Добавлено: 20 ноя 2006, 23:59
Хыиуду
Ну я прямо даже не знаю...
Ну можно вычислить эту сумму, каждый раз беря в знаменателе не 1, а, например, 65536, а потом на 16 двоичных знаков сдвинуть запятую. Тогда точности хватит?

Добавлено: 21 ноя 2006, 08:01
john_1
не совсем понял .можешь код выложить?

Добавлено: 21 ноя 2006, 09:29
somewhere
Так ли я понял? Сумма S - есть 200 битовое число? Если так, то FPU хватит лишь на 80. Все махинации со сложением, делением и возведением в степень надо делать с 200 битовыми монстрами. Сложение и умножение (возведение в натуральную степень) - это просто, а вот с делением придеться повозиться.
Если все же я правильно понял, то могу выложить процедуры для работы с N-битовыми двоичными числами.

Добавлено: 21 ноя 2006, 09:52
john_1
выложи,я посмотрю

Добавлено: 21 ноя 2006, 20:31
somewhere
Как и обещал, выкладываю.

Первоначально есть форма, на ней:
3 едита - два для ввода чисел, один для результата
2 батона - умножить и разделить на 2.

Тип TBigBinNumber - по сути массив из байтов длиной в 200 бит. Организован так, что первые 8 бит - целая часть числа, остальные - дробная. Есть две основные функции - сложение и умножение. Числа беззнаковые, кому надо дорабатывайте сами.
С делением, как и говорил, надо повозиться - выложу чуть позже, работа знаете ли ... :-)
Есть еще функции:
- загрузки целого числа, потом добавлю дробные из Real или больше.
- выгрузки этого монстра в Real (или другой тип FP).
На ассемблере все гораздо компактней или красивей - не говоря уж о скорости, но за рамки раздела выходить не стал.
Пока все.

Код: Выделить всё

unit bbn;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type

  TBigBinNumber = array [0..24] of byte;

  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    btnMul: TButton;
    Edit3: TEdit;
    btnDiv2: TButton;
    procedure btnMulClick(Sender: TObject);
    procedure btnDiv2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  b	   : TBigBinNumber;

implementation

{$R *.dfm}

Function _binLoad(p1:Byte):TBigBinNumber;
begin
Result[0] := p1;
FillChar(Result[1], 24, 0);
end;

function _binAdd(p1,p2:TBigBinNumber):TBigBinNumber;
var x, w: word;
begin
W := 0;
for x:=24 downto 0 do
	begin
	W := P1[X]+P2[X] + w shr 8;
	Result[X] := byte(W);
	end;
end;

function _binMul(p1,p2:TBigBinNumber):TBigBinNumber;
var x, y, w : Word;
tmp  	: TBigBinNumber;
begin
Result := _binLoad(0);
For x:=24 downto 0 do
	begin
	w := 0;
	For y:=24 downto 0 do
		begin
		w := p1[x]*p2[y] + w shr 8;
		tmp[y] := byte(w);
		end;
	Result := _binAdd(Result, tmp);
	end;
end;

Function _binDiv2(p1:TBigBinNumber):TBigBinNumber;
var x 		 : Integer;
	oldcf, cf: Byte;
begin
oldcf := 0;
cf := 0;
For x:=0 to 24 do
	begin
	cf := p1[x] and 1;
	Result[x] := (p1[x] shr 1) or (oldcf shl 7);
	oldcf := cf;
	end;
end;

Function _binGetAsReal(p1:TBigBinNumber):Real;
var divizor : Real;
	x, y	: Integer;
begin
Result := 0;
Divizor := 128;
For X:=0 to 24 do
	for Y:=7 downto 0 do
		begin
		Result := Result + ((p1[X] shr Y) and 1) * divizor;
		divizor := divizor / 2;
		end;
end;

procedure TForm1.btnMulClick(Sender: TObject);
var p1,p2	: Integer;
begin
p1 := StrToInt(Edit1.Text);
p2 := StrToInt(Edit2.Text);
b := _binMul(_binLoad(p1), _binLoad(p2));
Edit3.Text := FloatToStrF(_binGetAsReal(b), ffFixed, 10, 13);
end;

procedure TForm1.btnDiv2Click(Sender: TObject);
begin
b := _binDiv2(b);
Edit3.Text := FloatToStrF(_binGetAsReal(b), ffFixed, 10, 13);
end;

end.

Добавлено: 22 ноя 2006, 08:43
LAngel
Есть такая библиотечка, libeay32.dll в ней множество функций для работы с большими числами неограниченной длины. Писал я для неё в своё время обвязку на дельфи, если интересно, могу выложить.

Добавлено: 22 ноя 2006, 10:32
somewhere
LAngel, все это конечно, хорошо. Но я думаю, парню в институт надо. Не потащит же он туда библиотеку с готовым кодом. ;-)