Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Мат, округлние [D4]


Страницы:   1 2 3

pasha_golub ©   (2004-10-28 14:59:00) 

Люди, добрые подскажите параметр для FPU 8087, которое нужно кинуть в Set8087CW для того, чтобы округление было не банковским, а математическим. Спасибо.


pasha_golub   (2004-11-04 12:04:00) [1]

Defunct ©   (29.10.04 18:43) [50]
Спасибо огромное, значит я не ошибался.


Defunct   (2004-10-29 18:43:00) [2]

> pasha_golub ©   (29.10.04 12:20) [47]
> Потому и задал его тут.

Округлений просто море, потому что округление выполняет уменьшение точности, а как вы сами понимаете уменьшить точность можно как угодно. Выбирайте то, что нужно именно вам.
Мат округление, бухгалтерское, до четного, и т.п.

> pasha_golub ©   (29.10.04 12:40) [49]

http://search2.intel.com/corporate/default.aspx?q=Intel+IA-32+software+developers+manual+download

Там три части vol 1-3.
вторая часть "instruction set reference" в двух книгах по ~600стр. vol 2A, vol 2B


pasha_golub   (2004-10-29 12:40:00) [3]

Еще вопрос не по теме. Подскажите, где взять мануал по АСМу с сайта Интела, а то я как-то не нашел, видно руки...


Romkin   (2004-10-29 12:30:00) [4]

Все очень просто: Округляют к четному, дабы избежать дрейфа при операциях вида
1 + 0.5 - 0.5 + 0.5 - 0.5 ... Если каждый раз округлять, то "к четному" будет держать 2. А "школьное" - увеличиваться!


pasha_golub   (2004-10-29 12:20:00) [5]

Ого, мужики развели.

Вообщем, на самом деле это вопрос тоже не мой, а друга. И он меня тоже ввел в пучину сомнений и раздумий. Потому и задал его тут. А оказалось все не так просто. Гы


pasha_golub   (2004-10-29 12:17:00) [6]

Ого, мужики развели.

Вообщем, на самом деле это вопрос тоже не мой, а друга. И он меня тоже ввел в пучину сомнений и раздумий. Потому и задал его тут. А оказалось все не так просто. Гы


GuAV   (2004-10-29 02:17:00) [7]

Defunct ©   (29.10.04 1:13) [43]
32124323134998536792.5 (на нем уже все функции неправильно округляют).

:)
Точнее сказать такое число просто не может быть представленно с точностью выше целых. Т.е. .5 никуда не помещается. И функции уже ни при чём.

Defunct ©   (29.10.04 1:13) [43]
Eсли же работать с огромными числами (правильнее сказать с очень высокой точностью больше 50 знаков в числе), тогда ни ваша функция, ни функция Verg не помогут.

Названные функции работают при точности больше 50 двоичных знаков. О больше чем 64 знаках речь конечно идти не может - это уже действительно предел точности FPU.


Verg   (2004-10-29 01:51:00) [8]


> Давайте применим это правило к числам около нуля.
>


Давайте

0.5 + (-0.5) = 0

Что нам даст "жлобское" округление слагаемых? 1 + (-1) = 0 - тот же 0
Так, а теперь round( x + E)  -> 1 + 0 = 1

Так какое же округление на самом деле "жлобское"?


Defunct   (2004-10-29 01:13:00) [9]

GuAV ©   (29.10.04 01:02) [41]

Понимаете, особой разницы нет на каком знаке произойдет сбой
или на числе 212432313499856792.5 или на числе 32124323134998536792.5 (на нем уже все функции неправильно округляют).  Если просто работать с обычными числами (не гигантскими) тогда достаточно обойтись с помощью [12]. Eсли же работать с огромными числами (правильнее сказать с очень высокой точностью больше 50 знаков в числе), тогда ни ваша функция, ни функция Verg не помогут. Но, как правило, такая точность нигде не требуется.


Defunct   (2004-10-29 01:02:00) [10]

Verg ©   (29.10.04 00:41) [39]

> Можете еще с excel-ом поиграться.

Не, там жлобское округление.
если кредит (отрицательные числа) забирать больше.
если долг - отдавать меньше ;)

Есть еще бухгалтерское округление - обрезать до целого
(чтобы не платить лишнего) ;>

> Образует какое-то "альтернативное" понятие математического округления :))

Как в советской школе учили. округлять к большему. ;>

в яндексе правило округления отрицательных чисел должно быть. Там оно как в советской школе - к большему.


GuAV   (2004-10-29 01:02:00) [11]

Ну так, я и говорю, что Вы не можете написать E для кода где входные данные заранее неизвестны, поэтому при использовании Вашей функции нужно учитывать эти ограничения.
Это ни как не увязывается с

> "Программист! ДЕЛАЙ ВСЕ ПРОЩЕ".


Defunct   (2004-10-29 00:53:00) [12]

GuAV ©   (29.10.04 00:35) [38]

Извините, но вы показываете свое неумение слушать.

X:=212432313.4998567925;

Конкретно в этом числе порядок наименьшего значащей цифры (5) = 10(-10). Соответственно E = 10(-11).
Все упирается в точность.

Опять же

Z:=212432313499856792.5;

при E=0.01 округлит верно.

для полноты картины надо бы добавить еще и
Y = 3212432313499856792.5;

В общем если вы пытаетесь показать ограниченность мантиссы, так с этим никто не спорит.


Verg   (2004-10-29 00:41:00) [13]

Можете еще с excel-ом поиграться. Тот использует математическое округление без правила "четной цифры". Функция =ОКРУГЛ().

А


>В математике все же округление идет к большему целому.
> Const E = 0.000000000001;
>
> Round( Число + E );


Образует какое-то "альтернативное" понятие математического округления :))


GuAV   (2004-10-29 00:35:00) [14]

Defunct ©   (28.10.04 23:33) [32]
Док-во - конкретный пример где такое округление даст сбой

procedure TForm1.FormCreate(Sender: TObject);
var X, X1, Z, Z1: Extended;  S: string; OldMode: TFPURoundingMode;
begin
 Z:=212432313499856792.5;
 X:=212432313.4998567925;

 Memo1.Lines.Add('Defunct');

 Z1:=Round(Z + 0.001);
 X1:=Round(X + 0.001);
 Memo1.Lines.Add(FloatToStrF(Z1, ffFixed, 22, 2));
 Memo1.Lines.Add(FloatToStrF(X1, ffFixed, 22, 2));

 Memo1.Lines.Add('Verg');

 Z1:=Trunc(Z) + Trunc (Frac(Z) * 2);
 X1:=Trunc(X) + Trunc (Frac(X) * 2);
 Memo1.Lines.Add(FloatToStrF(Z1, ffFixed, 22, 2));
 Memo1.Lines.Add(FloatToStrF(X1, ffFixed, 22, 2));

 Memo1.Lines.Add('GuAV');

  OldMode := SetRoundMode(rmDown);
  try
    Z1:=Round(Z + 0.5);
    X1:=Round(X + 0.5);
  finally
    SetRoundMode(OldMode);
  end;

 Memo1.Lines.Add(FloatToStrF(Z1, ffFixed, 22, 2));
 Memo1.Lines.Add(FloatToStrF(X1, ffFixed, 22, 2));

end;


Defunct   (2004-10-29 00:31:00) [15]

Verg ©   (29.10.04 00:04) [36]

ага нашел.

Округление состоит в отбрасывании, точнее в замене нулями, всех цифр, стоящих правее цифры данного разряда. Если при этом первой из отбрасываемых цифр является 0, 1, 2, 3 или 4 , последняя остающаяся цифра не меняется; если же первой из отбрасываемых цифр окажется 5, 6, 7, 8 или 9 , последняя остающаяся цифра увеличивается на 1

Давайте применим это правило к числам около нуля.

-0.6 = -1
-0.5 = -1
-0.4 = 0
-0.3 = 0
-0.2 = 0
-0.1 = 0
0    = 0
0.1  = 0
0.2  = 0
0.3  = 0
0.4  = 0
0.5  = 1

Получается почему-то 9 нулей хотя должно быть 10. ведь целое складывается из десяти десятых, а не из девяти.
Выводы:
1. 0 - не целое число (но это не так).
2. метод округления указан не точно. И действительно в приведенной статье нет правила округления отрицательных чисел.


Verg   (2004-10-29 00:04:00) [16]


> [34] Defunct ©   (28.10.04 23:56)


http://www.sgu.ru/ie/mehmat/matin/R1-4.htm


False_Delirium   (2004-10-29 00:04:00) [17]

Defunct ©   (28.10.04 23:56) [34]  
 Математическое округление -1.5 даёт -1

и кто говорит обратное - идёт в туман :))


Defunct   (2004-10-28 23:56:00) [18]

> Verg

> http://www.sgu.ru/ie/mehmat/matin/

Извини, но я там не нашел ни слова про округление..

То, что по второй ссылке -1.5 = -2 я поверю наслово.


sniknik   (2004-10-28 23:54:00) [19]

> а на 2.001 что получим?
обана, а мужики то не в курсе. ;о)

сорри, действительно ерунда получилась.


Defunct   (2004-10-28 23:33:00) [20]

GuAV ©   (28.10.04 22:15) [26]
> Я уже доказал.
Не не доказал.
Док-во - конкретный пример где такое округление даст сбой, а ваш способ и ф-ция Verg округлит правильно.


> Вот допустим ххх.5 и .5 в последнем знаке, прибавление 0.1 не
> изменит число, и если оно нечётноё, оно округлится в меньшую
> сторону ка и просто Round.

Давайте без допустим. Допустим в мантиссу не влазит дробная часть вообще. В общем это чушь а не доказательство.


> Вот и получается: как не крути, а ОКРУГЛЕНИЕ(-1.5)  = -2

В математике все же округление идет к большему целому.

Просто и со вкусом:

Const E = 0.01;

procedure TForm1.Button8Click(Sender: TObject);
begin
 ShowMessage( Format(']-2.5[ = %D',[ Round(-2.5 + E) ] ));
 ShowMessage( Format(']-1.5[ = %D',[ Round(-1.5 + E) ] ));
 ShowMessage( Format(']1.5[ = %D',[ Round(1.5 + E) ] ));
 ShowMessage( Format(']2.5[ = %D',[ Round(2.5 + E) ] ));
end;


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо