| 
| 
 | Вопрос # 6 473/ вопрос решён / | 
 |  Доброго времени суток.Подскажите функцию с учетом моих нулевых знаний.
 
|  |   Вопрос задал: zvygin1964 (статус: Посетитель)Вопрос отправлен: 29 августа 2013, 23:37
 Состояние вопроса: решён, ответов: 1.
 |  Ответ #1. Отвечает эксперт: min@y™ // Преобразование целого в двоичную строку и дополнение слева нулями до длины P
function Int2Bin(const X: Integer; const P: Byte): string;
var
  i: Integer;
begin
  Result:= '';
  i:= X;
 
  repeat
    if (i and 1) = 0
      then Result:= '0' + Result
      else Result:= '1' + Result;
 
      i:= i shr 1;
  until i = 0;
 
  while Length(Result) < P do
    Result:= '0' + Result;
end;
|  | Ответ отправил: min@y™ (статус: Доктор наук)Время отправки: 30 августа 2013, 00:00
 Оценка за ответ: 5
 Комментарий к оценке: Спасибо. Проверяю. |  
 Мини-форум вопросаВсего сообщений: 18; последнее сообщение — 16 сентября 2013, 20:16; участников в обсуждении: 3. 
|   | min@y™ (статус: Доктор наук), 30 августа 2013, 00:08 [#1]:Эту функцию можно здорово оптимизировать, чтобы она работала на порядок быстрее. Достаточно сделать так, чтобы под результирующую строку память выделялась 1 раз. Этот вариант функции я выдрал из своего старого проекта, который ещё в детском саду писал, так что извини.  
 З.Ы. Кстати, ты ж знаток ассемблера, чо ж на асме не написал простейшее преобразование?
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | min@y™ (статус: Доктор наук), 30 августа 2013, 00:52 [#2]:Типа как-то так: 
 // Преобразование целого в двоичную строку и дополнение слева нулями до длины P
// Максимальное кол-во разрядов нужно знать заранее!
function Int2Bin(const X: Integer; const P: Byte): string;
var
  i, Index: Integer;
begin
  SetLength(Result, P);        // выделение памяти
  FillChar(Result[1], P, '0'); // заполнение нулями до длины P
 
  i:= X;
 
  for Index:= P downto 1 do
    begin
      if (i and 1) <> 0
        then Result[Index]:= '1';
 
      i:= i shr 1;
 
      if i = 0
        then Break;
    end;
end;Ахтунг! Не отлаживал, писал на пузе.
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | zvygin1964 (статус: Посетитель), 30 августа 2013, 09:14 [#3]:Мои познания assembler не  имеют отношения к математике (управление портами ввода-вывода, таймеры, UART интерфейс микроконтроллеров ATMEL) и всё. Учил таким же способом на  easyelectronics.ru. |  
|   | min@y™ (статус: Доктор наук), 30 августа 2013, 11:25 [#4]: Цитата (zvygin1964): Мои познания assembler не имеют отношения к математике А нафига тут математика? Все данные 1хрен хранятся в двоичном виде. А строка - это просто массив байтов.
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | DNK (статус: Студент), 2 сентября 2013, 12:57 [#5]:Ахтунг принимается.  
 Цитата: Delphi syntax:
 procedure FillChar(var X; Count: Integer; Value: Byte);
 
 Соотвественно нужно исправить:
 
 FillChar(Result[1], P, Ord('0')); // заполнение нулями до длины PНо я бы сделал так:
 
 Result := StringOfChar('0', P); // заполнение нулями до длины P"Digital Networked Knight" |  
|   | min@y™ (статус: Доктор наук), 2 сентября 2013, 14:15 [#6]: Цитата (DNK): Но я бы сделал так молодец!
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | zvygin1964 (статус: Посетитель), 3 сентября 2013, 12:19 [#7]:Ответ #1 от min@y™ работает. unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Memo1: TMemo;
 
  procedure Edit1Change(Sender: TObject);
    procedure Button1Click(Sender: TObject);
 
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  i: Integer;
implementation
 
{$R *.dfm}
 
function Int2Bin(const X: Integer; const P: Byte): string;
var   {подарок от уважаемого min@y™ expert.delphi.int.ru (я должен пиво!}
  i: Integer;
begin
  Result:= '';
  i:= X;
 
  repeat
    if (i and 1) = 0
      then Result:= '0' + Result
      else Result:= '1' + Result;
 
      i:= i shr 1;
  until i = 0;
 
  while Length(Result) < P do {,где P количество отображаемых байт}
    Result:= '0' + Result;
end;
// программа начинается отсюда ======================
procedure TForm1.Edit1Change(Sender: TObject);
begin
   i:=StrToInt(Edit1.Text);  {читаю исходное десятичное число (вероятно и др.)}
end;
 
procedure TForm1.Button1Click(Sender: TObject);
  var
  j: string;
begin
   j:=Int2Bin(i,8); {от уважаемого min@y™ expert.delphi.int.ru}
   Form1.Memo1.Lines.Add(j); {вывожу результат}
end;
 
end.Продолжаю проверку ответа #2 с добавлениями DNK #5.
 Извините, но это займет несколько дней... (большие пробелы в воспитании).
 |  
|   | zvygin1964 (статус: Посетитель), 3 сентября 2013, 14:15 [#8]:Работает: FillChar(Result[1], P, Ord('0')); // заполнение нулями до длины P!Дополнение #5 от  DNK работает:
 unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Memo1: TMemo;
 
  procedure Edit1Change(Sender: TObject);
    procedure Button1Click(Sender: TObject);
 
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  i: Integer;
implementation
 
{$R *.dfm}
 
{Преобразование целого в двоичную строку и дополнение слева нулями до длины P}
{Максимальное кол-во разрядов:P=8 количество бит в байте (нужно знать заранее)}
function Int2Bin(const X: Integer; const P: Byte): string;
var
  i, Index: Integer;
begin
  SetLength(Result, P);        // выделение памяти
  //FillChar(Result[1], P, Ord('0')); {это было до исправления}
  Result := StringOfChar('0', P); //исправление #5 DNK(Абитуриент)(спасибо ему)
                                  // http://expert.delphi.int.ru
  i:= X;
 
  for Index:= P downto 1 do
    begin
      if (i and 1) <> 0
        then Result[Index]:= '1';
 
      i:= i shr 1;
 
      if i = 0
        then Break;
    end;
end;
 
{программа начинается отсюда ===========================}
 
procedure TForm1.Edit1Change(Sender: TObject);
begin
   i:=StrToInt(Edit1.Text);  {читаю исходное десятичное число (вероятно и др.)}
end;
 
procedure TForm1.Button1Click(Sender: TObject);
  var
  j: string;
begin
   j:=Int2Bin(i,8);          //от уважаемого min@y™ expert.delphi.int.ru
   Form1.Memo1.Lines.Add(j); //вывожу результат (Я должен пиво !)
end;
 
end.Спасибо!Пиво уважаемому min@y™ выслал.
 |  3 сентября 2013, 14:18: Статус вопроса изменён на решённый (изменил автор вопроса — zvygin1964) 
|   | DNK (статус: Студент), 3 сентября 2013, 14:21 [#9]:zvygin1964: Если используешь StringOfChar, то предварительный SetLength не нужен, функция сама выделит нужную память. "Digital Networked Knight" |  
|   | min@y™ (статус: Доктор наук), 3 сентября 2013, 19:16 [#10]:Обработчик события Edit1.OnChange и глобальная переменная i тут нахрен не нужна. Выкинь. 
 procedure TForm1.Button1Click(Sender: TObject);
var
  X: Integer;
begin
  if TryStrToInt(Edit1.Text, X)
    then Memo1.Lines.Add(Int2Bin(X, 8)) //вывожу результат 
    else ShowMessage('Ошибка: некорректный ввод числа.');
end;Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | zvygin1964 (статус: Посетитель), 4 сентября 2013, 16:17 [#11]:Спасибо, имя глобальной переменной изменю. В этом варианте она ( var
 Form1: TForm1;
 i: Integer;
 implementation; {
 ) может и не нужна. Но ваша подпрограмма Int2Bin будет работать без окошка Edit1, да и без Button1. Данные будут присваиваться прямо из этой глобальной переменной.
 Проверка:
 if TryStrToInt(Edit1.Text, X)
 then Memo1.Lines.Add(Int2Bin(X, 8)) //вывожу результат
 else ShowMessage('Ошибка: некорректный ввод числа.');
 в учебных это хорошо, но мои данные будут заведомо в интервале 0-255. Мой микроконтроллер их и создаст, другого из порта ввода-вывода получить не удастся. А ShowMessage если выскочит (удар молнии в кофеварку или другое наводнение), то накроет работу программы.
 |  
|   | min@y™ (статус: Доктор наук), 4 сентября 2013, 16:54 [#12]: Цитата (zvygin1964): Спасибо, имя глобальной переменной изменю. Ты чо, не понял? Она вообще тут не нужна, как бы ты её не называл. Выбрось её.
 
 Цитата (zvygin1964): Данные будут присваиваться прямо из этой глобальной переменной. Очень советую использовать глобальные переменные тогда и только тогда, когда без них обойтись невозможно! Во всех остальных случаях используй локальные переменные, передавая их в функции в качестве параметров.
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | zvygin1964 (статус: Посетитель), 4 сентября 2013, 21:42 [#13]:"передавая их в функции в качестве параметров",- до понятия этого я не дорос. "вообще тут не нужна",- это я понял. |  
|   | zvygin1964 (статус: Посетитель), 4 сентября 2013, 21:45 [#14]:"использовать глобальные переменные тогда и только тогда, когда без них обойтись невозможно",- это пока в тумане. Я предложенный Вами учебник читать только начал. Очень понравилось предисловие. |  
|   | min@y™ (статус: Доктор наук), 4 сентября 2013, 22:10 [#15]: Цитата (zvygin1964): "передавая их в функции в качестве параметров",- до понятия этого я не дорос. Читай в томе 1 в главе 2 раздел "Процедуры и функции". Там разжёвано.
 
 Цитата (zvygin1964): "вообще тут не нужна",- это я понял. Сомневаюсь.
 
 Цитата (zvygin1964): "использовать глобальные переменные тогда и только тогда, когда без них обойтись невозможно",- это пока в тумане. Просто поверь наслово.
 
 Цитата (zvygin1964): Очень понравилось предисловие. Это предисловие писал я.
   Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | zvygin1964 (статус: Посетитель), 4 сентября 2013, 22:26 [#16]:"Это предисловие писал я", - Оооо!!!  Пошел читать Стива Тейксейра и Ксавье Пачеко 10 раз. С первого раза ничего не понимаю. |  
|   | min@y™ (статус: Доктор наук), 16 сентября 2013, 19:27 [#17]: Цитата (zvygin1964): Напугали. Боюсь теперь задавать вопросы! Но спасибо много раз. Не понял... Чо я такого страшного сказал?
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | zvygin1964 (статус: Посетитель), 16 сентября 2013, 20:16 [#18]:Нет. Все нормально. Это просто я такой пугливый. |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |