Форум программистов, компьютерный форум, киберфорум
Наши страницы

Delphi для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 69, средняя оценка - 4.61
hisp
0 / 0 / 0
Регистрация: 03.11.2010
Сообщений: 14
#1

Перевод числа в строку и обратно - Delphi

04.04.2011, 01:57. Просмотров 10252. Ответов 4

Дело в следующем: когда считаются погрешности и переводятся в строку числа странные получаются.
Например: 1,99-1,96 получается результат 0,02999999999. Я понимаю, что юзать FloatToStr и StrToFloat в рассчётах - это моветон, но другого выхода не знаю.
И проверка погрешностей не осуществляется, вроде смотрел, чему равны переменные, вводил их значение, но все равно говорит, что неправильно.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
procedure TForm6.Button1Click(Sender: TObject);
var
   volt1,volt2,volt3,volt4,volt5        :real; //переменные для StrGrid1
   pog1,pog2,pog3,pog4,pog5     :real; //расчет погрешности
   aa1, aa2, aa3,aa4,aa5 :real; //для расчета Д
   aSHk2                 :real; //эталонные значения
   aSHk3                 :real; //------------------
 
 
 
begin
 aSHk2 := 1.99;
 aSHk3 := 2;
 
   volt1 := StrToFloat (StringGrid1.Cells [1,1]);// ----------------------------------
   volt2 := StrToFloat (StringGrid1.Cells [1,2]);//
   volt3 := StrToFloat (StringGrid1.Cells [1,3]);//ввод значений в поле для погрешностей
   volt4 := StrToFloat (StringGrid1.Cells [1,4]);//
   volt5 := StrToFloat (StringGrid1.Cells [1,5]);//------------------------------------
 
   aa1:= StrToFloat (StringGrid2.Cells [1,1]);
   aa2:= StrToFloat (StringGrid2.Cells [1,2]);
   aa3:= StrToFloat (StringGrid2.Cells [1,3]);
   aa4:= StrToFloat (StringGrid2.Cells [1,4]);
   aa5:= StrToFloat (StringGrid2.Cells [1,5]);
 
//расчет погрешностей
   if (sTT1>aSHk2) then
      pog2:=sTT1-aSHk2
      else
     pog2:= aSHk2-sTT1;
 
    if (sP323>aSHk3) then
      pog3:=sP323-aSHk3
      else
      pog3:=aSHk3-sP323;
 
   if (sB338>aSHk2) then
      pog4:=sB338-aSHk2
      else
      pog4:=aSHk2-sB338;
 
   if (sBK79>aSHk2) then
      pog5:=sBK79-aSHk2
      else
      pog5:=aSHk2-sBK79;
 
 
//проверка показаний         
if (aa1 = 0) and (aa2 = sTT1) and (aa3 = sP323) and (aa4 = sB338) and (aa5 = sBK79) then
    MessageDlg('Все верно', mtInformation, [mbOK], 0)            
    MessageDlg('Сопоставлено неверно', mtError, [mbOK], 0);
//проверка погрешностей
if (volt1=0) and (volt2=pog2) and (volt3=pog3) and (volt4=pog4) and (volt5=pog5)then
 
    MessageDlg('Все верно', mtInformation, [mbOK], 0)            
else
    MessageDlg('Сопоставлено неверно', mtError, [mbOK], 0);
 
 
end;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.04.2011, 01:57
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Перевод числа в строку и обратно (Delphi):

Перевод десятичного числа в шестнадцатеричную систему счисления, и обратно - Delphi
Цикл с пред условием: Написать программу для перевода десятичного числа в шестнадцатеричную систему исчисления, и обратно. Число вводится...

перевод числа в строку - Delphi
Подскажите, как реализовать функцию перевода числа в строку не используя стандартных функций delphi? функция должна выглядеть: ...

Перевод строки в число с плавающей точкой и обратно - Delphi
на форме есть Edit/Label/Button (всех по одному), нужно из поля Edit вытащить число с плавающей точкой, выполнить с ним пару математических...

Перевод числа с плавающей точкой в hex и обратно - Delphi
Доброго времени суток. Имеется число в hex - 3E4CCCCD. Заведомо известно его значение: 0,2. Прошу помочь реализовать перевод из hex и...

1. простые числа в массиве 2. перевод числа в строку - Delphi
Здравствуйте. очень нужна помощь по программированию 1. удалить простые числа из массива у меня получилось вот так: a: array...

Перевод из текста в hex и обратно - Delphi
Доброго времени суток. Прошу помощи в решении задачи: в edit вводим текст к примеру "Конст", по нажатию button1 в edit2 переводит текст в...

4
chum
51 / 50 / 2
Регистрация: 19.01.2010
Сообщений: 139
04.04.2011, 02:36 #2
Цитата Сообщение от hisp Посмотреть сообщение
Дело в следующем: когда считаются погрешности и переводятся в строку числа странные получаются.
Например: 1,99-1,96 получается результат 0,02999999999.
[/DELPHI]
Может быть, мною неверно понят вопрос и проблема, но если вдруг загвоздка с преобразованием числа в строку (1,99-1,96 получается результат 0,02999999999), то вместо FloatToStr можно попробовать использовать FloatToStrF. Вот абстрактный пример, где результат выводится с тремя знаками после запятой:
StringGrid2.Cells[J+1,I+1]:=FloatToStrF(InversMatr.Data[I,J],ffFixed,3,3);
1
hisp
0 / 0 / 0
Регистрация: 03.11.2010
Сообщений: 14
04.04.2011, 17:26  [ТС] #3
Цитата Сообщение от chum Посмотреть сообщение
Может быть, мною неверно понят вопрос и проблема, но если вдруг загвоздка с преобразованием числа в строку (1,99-1,96 получается результат 0,02999999999), то вместо FloatToStr можно попробовать использовать FloatToStrF. Вот абстрактный пример, где результат выводится с тремя знаками после запятой:
StringGrid2.Cells[J+1,I+1]:=FloatToStrF(InversMatr.Data[I,J],ffFixed,3,3);
Спасиб, вот только когда сравниваю вводимое в грид число и посчитанную погрешность, сравнение странно происходит . Т.е ввожу например 0,03 - правильно, а он мне говорит , что нет. Это не может быть из за десятичного разделителя? Или это опять косяк перевода вещественного числа в строку?
0
Mawrat
12820 / 5728 / 676
Регистрация: 19.09.2009
Сообщений: 8,807
04.04.2011, 19:32 #4
hisp, потому что вещественные числа нельзя сравнивать на "равно".
Чтобы было ясно, предлагаю выполнить вот этот код:
Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure TForm1.Button1Click(Sender: TObject);
var
  A : Double;
begin
  A := 0.1;
  if A = 0.1 then
    ShowMessage('0.1 = 0.1')
  else
    ShowMessage('0.1 <> 0.1')
  ;
end;
В результате выполнения этого кода будет выведено сообщение: "0.1 <> 0.1". Это связано с погрешностью представления вещественных чисел в памяти компьютера. Число 0.1 не может быть представлено в виде конечной двоичной дроби. Поэтому младшие дробные разряды, которые не уместились в формат типа Extended будут отсечены. Затем, когда выполняется операция:
A := 0.1;
Будут опять отсечены младшие разряды - согласно возможностям типа Double.
И когда будет выполняться сравнение:
if A = 0.1 then
произойдёт следующее: число, записанное в А будет приведено к типу Extended. При этом младшие дробные разряды, которые при этом добавятся, заполнятся нулями. Константа 0.1 тоже будет преобразована к типу Extended при этом никакие дробные разряды обнулены не будут. Поэтому окажется что левый операнд не равен правому операнду.
---
Поэтому, во-первых, желательно везде где возможно пользоваться типом Extended. Во вторых, даже если применять только Extended, при множественных вычислениях будет накапливаться погрешность связанная с точностью типа Extended. Поэтому сравнения вещественных чисел на "равно" надо заменить на сравнение на равно с заданной точностью. Например:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm1.Button1Click(Sender: TObject);
const
  //Погрешность представления чисел типа Double.
  Eps = 1e-15;
var
  A : Double;
begin
  A := 0.1;
  if Abs(A - 0.1) <= Eps then
    ShowMessage('0.1 = 0.1')
  else
    ShowMessage('0.1 <> 0.1')
  ;
end;
Здесь уже ответ будет таким: "0.1 = 0.1".
Либо можно применять гуппу перегружаемых функций SameValue() из модуля Math:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
uses
  Math;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  A : Double;
begin
  A := 0.1;
  if SameValue(A, 0.1) then
    ShowMessage('0.1 = 0.1')
  else
    ShowMessage('0.1 <> 0.1')
  ;
end;
В этом случае ответ тоже будет таким: "0.1 = 0.1".
2
hisp
0 / 0 / 0
Регистрация: 03.11.2010
Сообщений: 14
05.04.2011, 01:48  [ТС] #5
Цитата Сообщение от Mawrat Посмотреть сообщение
hisp, потому что вещественные числа нельзя сравнивать на "равно".
Чтобы было ясно, предлагаю выполнить вот этот код:
Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure TForm1.Button1Click(Sender: TObject);
var
  A : Double;
begin
  A := 0.1;
  if A = 0.1 then
    ShowMessage('0.1 = 0.1')
  else
    ShowMessage('0.1 <> 0.1')
  ;
end;
В результате выполнения этого кода будет выведено сообщение: "0.1 <> 0.1". Это связано с погрешностью представления вещественных чисел в памяти компьютера. Число 0.1 не может быть представлено в виде конечной двоичной дроби. Поэтому младшие дробные разряды, которые не уместились в формат типа Extended будут отсечены. Затем, когда выполняется операция:
A := 0.1;
Будут опять отсечены младшие разряды - согласно возможностям типа Double.
И когда будет выполняться сравнение:
if A = 0.1 then
произойдёт следующее: число, записанное в А будет приведено к типу Extended. При этом младшие дробные разряды, которые при этом добавятся, заполнятся нулями. Константа 0.1 тоже будет преобразована к типу Extended при этом никакие дробные разряды обнулены не будут. Поэтому окажется что левый операнд не равен правому операнду.
---
Поэтому, во-первых, желательно везде где возможно пользоваться типом Extended. Во вторых, даже если применять только Extended, при множественных вычислениях будет накапливаться погрешность связанная с точностью типа Extended. Поэтому сравнения вещественных чисел на "равно" надо заменить на сравнение на равно с заданной точностью. Например:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm1.Button1Click(Sender: TObject);
const
  //Погрешность представления чисел типа Double.
  Eps = 1e-15;
var
  A : Double;
begin
  A := 0.1;
  if Abs(A - 0.1) <= Eps then
    ShowMessage('0.1 = 0.1')
  else
    ShowMessage('0.1 <> 0.1')
  ;
end;
Здесь уже ответ будет таким: "0.1 = 0.1".
Либо можно применять гуппу перегружаемых функций SameValue() из модуля Math:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
uses
  Math;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  A : Double;
begin
  A := 0.1;
  if SameValue(A, 0.1) then
    ShowMessage('0.1 = 0.1')
  else
    ShowMessage('0.1 <> 0.1')
  ;
end;
В этом случае ответ тоже будет таким: "0.1 = 0.1".
Спасибо , дошло как все сделать)))
0
05.04.2011, 01:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.04.2011, 01:48
Привет! Вот еще темы с ответами:

Exe в строку и обратно - Delphi
Нужно преобразовать exe в строку для передачи через поле blob MySQL. Код нашел в инете, в результате созданный 0.exe не запускается. В чем...

Перевод перестановки из записи второй строкой в запись в виде произведения независимых циклов и обратно - Delphi
Перевод перестановки из записи второй строкой в запись в виде произведения независимых циклов и обратно

Как пять бит перевести в строку и обратно? - Delphi
Будьте добры, подскажите не могу сообразить что-то Есть пять переменных типа bool b1,b2,b3,b4,b5 нужно из них сделать одну...

Как создать компоненту перевода арабского числа в римское и обратно? - Delphi
Как создать компоненту перевода арабского числа в римское и обратно?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru