Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 6 473

/ вопрос решён /

Доброго времени суток.
Подскажите функцию с учетом моих нулевых знаний.

Приложение:
  1. var
  2. d: Byte;
  3. e: String;
  4. begin
  5.  
  6.  


zvygin1964 Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: 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™

min@y™ (статус: Доктор наук), 30 августа 2013, 00:08 [#1]:

Эту функцию можно здорово оптимизировать, чтобы она работала на порядок быстрее. Достаточно сделать так, чтобы под результирующую строку память выделялась 1 раз. Этот вариант функции я выдрал из своего старого проекта, который ещё в детском саду писал, так что извини. :)

З.Ы. Кстати, ты ж знаток ассемблера, чо ж на асме не написал простейшее преобразование?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
min@y™

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

zvygin1964 (статус: Посетитель), 30 августа 2013, 09:14 [#3]:

Мои познания assembler не имеют отношения к математике (управление портами ввода-вывода, таймеры, UART интерфейс микроконтроллеров ATMEL) и всё. Учил таким же способом на easyelectronics.ru.
min@y™

min@y™ (статус: Доктор наук), 30 августа 2013, 11:25 [#4]:

Цитата (zvygin1964):

Мои познания assembler не имеют отношения к математике

А нафига тут математика? Все данные 1хрен хранятся в двоичном виде. А строка - это просто массив байтов.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
DNK

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™

min@y™ (статус: Доктор наук), 2 сентября 2013, 14:15 [#6]:

Цитата (DNK):

Но я бы сделал так

молодец!
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
zvygin1964

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

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

DNK (статус: Студент), 3 сентября 2013, 14:21 [#9]:

zvygin1964: Если используешь StringOfChar, то предварительный SetLength не нужен, функция сама выделит нужную память.
"Digital Networked Knight"
min@y™

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

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™

min@y™ (статус: Доктор наук), 4 сентября 2013, 16:54 [#12]:

Цитата (zvygin1964):

Спасибо, имя глобальной переменной изменю.

Ты чо, не понял? Она вообще тут не нужна, как бы ты её не называл. Выбрось её.

Цитата (zvygin1964):

Данные будут присваиваться прямо из этой глобальной переменной.

Очень советую использовать глобальные переменные тогда и только тогда, когда без них обойтись невозможно! Во всех остальных случаях используй локальные переменные, передавая их в функции в качестве параметров.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
zvygin1964

zvygin1964 (статус: Посетитель), 4 сентября 2013, 21:42 [#13]:

"передавая их в функции в качестве параметров",- до понятия этого я не дорос. "вообще тут не нужна",- это я понял.
zvygin1964

zvygin1964 (статус: Посетитель), 4 сентября 2013, 21:45 [#14]:

"использовать глобальные переменные тогда и только тогда, когда без них обойтись невозможно",- это пока в тумане. Я предложенный Вами учебник читать только начал. Очень понравилось предисловие.
min@y™

min@y™ (статус: Доктор наук), 4 сентября 2013, 22:10 [#15]:

Цитата (zvygin1964):

"передавая их в функции в качестве параметров",- до понятия этого я не дорос.

Читай в томе 1 в главе 2 раздел "Процедуры и функции". Там разжёвано.

Цитата (zvygin1964):

"вообще тут не нужна",- это я понял.

Сомневаюсь.

Цитата (zvygin1964):

"использовать глобальные переменные тогда и только тогда, когда без них обойтись невозможно",- это пока в тумане.

Просто поверь наслово.

Цитата (zvygin1964):

Очень понравилось предисловие.

Это предисловие писал я. :)
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
zvygin1964

zvygin1964 (статус: Посетитель), 4 сентября 2013, 22:26 [#16]:

"Это предисловие писал я", - Оооо!!! Пошел читать Стива Тейксейра и Ксавье Пачеко 10 раз. С первого раза ничего не понимаю.
min@y™

min@y™ (статус: Доктор наук), 16 сентября 2013, 19:27 [#17]:

Цитата (zvygin1964):

Напугали. Боюсь теперь задавать вопросы! Но спасибо много раз.

Не понял... Чо я такого страшного сказал?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
zvygin1964

zvygin1964 (статус: Посетитель), 16 сентября 2013, 20:16 [#18]:

Нет. Все нормально. Это просто я такой пугливый.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 18 июня 2019, 01:58
Выполнено за 0.04 сек.
Рейтинг@Mail.ru