|
Вопрос # 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]:
Нет. Все нормально. Это просто я такой пугливый.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|