Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
54 / 54 / 5
Регистрация: 18.10.2009
Сообщений: 309
1

Забавный баг Делфи ...или не баг?

13.10.2011, 00:21. Просмотров 1053. Ответов 5
Метки нет (Все метки)

кароч кидаем на форму 2 editа и кнопку и пишем такой код
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
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var x:real;
begin
x:=1.7;
edit2.Text:=FloatToStr(x - strtofloat(edit1.text)) ;
end;
 
end.
А тепер введиде в edit1 значение равное переменной x(но важно чтоб она бла дробной 1.3; 1.5 итп)
и вы не получите ожидаемый 0 Выведет ахинею типо -4,44522890719057E-1

А теперь заделаем вот так:
Delphi
1
2
3
4
5
6
7
procedure TForm1.Button1Click(Sender: TObject);
var x,y:real;
begin
x:=1.7;
y:=1.7;
edit2.Text:=FloatToStr(x - y) ;
end;
И, о чудо, мы получаем долгожданый 0! Кто мне обьяснить почему первый способ не работает???
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.10.2011, 00:21
Ответы с готовыми решениями:

Ошибка кода или баг?
Связано с ini файлами: Имеется код const SECTION_NAME = 'MAIN'; VALUE_NAME = 'version'; ...

Магия модулей или баг дельфи? Не подключается модуль JPEG
Скрин: https://www.cyberforum.ru/attachment.php?attachmentid=955135&stc=1&d=1532429080 с чем...

Баг в FloatToStr или во мне?
В общем, решил сделать калькулятор (да, ещё один велосипед). Вроде всё работало, но вот вдруг...

Баг или что? как исправить
procedure TForm1.Button5Click(Sender: TObject); var a,b,e,x0,x,F2,F1,n,F,C:real; //...

5
5343 / 2055 / 439
Регистрация: 20.11.2009
Сообщений: 6,822
Записей в блоге: 1
13.10.2011, 00:34 2
у меня 0 выводит
0
Миниатюры
Забавный баг Делфи ...или не баг?  
2181 / 1251 / 143
Регистрация: 28.04.2010
Сообщений: 4,592
13.10.2011, 00:35 3
вот так делай
Delphi
1
FloatToStr(x - roundto(strtofloat(edit1.text),-2)) ;
и добавь модуль math
0
5343 / 2055 / 439
Регистрация: 20.11.2009
Сообщений: 6,822
Записей в блоге: 1
13.10.2011, 00:36 4
мда... я тупой бывает... и что я доказал то, что и ты доказал 2 кодом ))
хотя сделал как ты написал что ахинею пишет - действительно пишет, потом поставил тип Extended и все ок
0
Заблокирован
13.10.2011, 08:21 5
Это не баг дельфи, а Ваш баг Размерность типов разная, т.е. у Вас x = real, т.е. Double - 8-ми байтовое с плавающей точкой. а Extended = 10 байтовое с плавающей точкой... Объявите x как extended - пропадет погрешность (погрешность в 17 знаке после запятой, что правильно, ведь точность doublе - 16 знаков после запятой). А функция StrToFloat - возвращает тип Extended, а у него 20 знаков после запятой... Вот и все объяснение.
Одним словом RTFM! Учите матчасть, господа программеры
Попробуйте такой код:
Delphi
1
2
3
4
5
6
var
  x1: real;
begin
  x1 := 1.1;
  edit1.Text := FormatFloat('0.00000000000000000000', x1) ;
end
А потом такой:
Delphi
1
2
3
4
5
6
var
  x1: extended;
begin
  x1 := 1.1;
  edit1.Text := FormatFloat('0.00000000000000000000', x1) ;
end
1
4194 / 1787 / 211
Регистрация: 24.11.2009
Сообщений: 27,563
13.10.2011, 10:06 6
Если вычитать функцию преобразования из переменной, то не факт, что временная величина будет иметь в точности ту же разрядность, что и переменная. А при другой разрядносити может отличаться и значение из-за разной точности округления. Фокус в том, что комп то двоичный, а преобразуемая дробь десятичная. А теперь пробуем преобразовать 1,7 десяточное в двоичню дробь. Одна целая так и будет 1. Значит 1,... Теперь 7 десятых. Умножаем на основание (2), получаем одну целую, 4 десятых. Значит, 1,1... Теперь 4 десятых умножаем на два, получаем 0 целых, 8 десятых. Значит 1,10... 0,8*2=1,6. 1,101... 0,6*2=1,2. 1,1011... 0,2*2=0,4. 1,10110... 0,4*2=0,8. 1,101100... 0,8*2=1,6. 1,101101... 0,6*2=1,2 период видим? 1,7d=1,10(1100)b. Двробь бесконечна. Теперь округляем её с разной точностью, потом одно из другого вычистаем: 1,7d-1,7d=1,101100110011001b-1,101100110011001100110011b=-0,000000000000000100110011b. Ахинея видна невооружённым глазом, но всё правильно. А если переменая равна 1,5, 1,25, 1,125, 1,75, 1,625 и или любому другому точно преобразуемому значению, то бага не будет. Броться с этим надо приводя к единой разрядности.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.10.2011, 10:06

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

std::regex : баг на сайте или баг компилятора?
http://en.cppreference.com/w/cpp/regex/regex_match этот код выкидывает throw... Добавлено через...

Баг asio? или баг TCP стека?
всем привет. повстречался с очень странным багом. и не могу определить кто бажит, asio, или...

Letter-spacing баг или не баг?
Здравствуйте! Использовал letter-spacing для увеличения расстояния между буквами. Как оказалось...

Баг в программе. Без цикла работает нормально. С циклом выдает баг
Здравствуйте. Пишу программу. И как не пытался ее переписать, как дохожу до момента включения в код...

Баг или фича ? =)
Thread threads = new Thread; for (int i = 0; i < threads.Length; i++) {...

Баг или нет
Функции char.IsDigit(); char.IsNumber(); работают идентично в VS2012 и не реагируют на...


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

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

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