Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2006.07.02;
Скачать: [xml.tar.bz2];

Вниз

MinSingle: Single = 1.5e-45; Почему?   Найти похожие ветки 

 
TSingle   (2006-06-03 06:36) [0]

Разве это число не должно быть отрицательным ?


 
Alx2 ©   (2006-06-03 07:17) [1]

Это так называемое машинное эпсилон для данного типа. Минимальное по модулю значение типа single, меньше которого по модулю будет уже только ноль.


 
Alx2 ©   (2006-06-03 07:22) [2]

Приблизительно такой код для определения:

procedure TDemoForm.Button1Click(Sender: TObject);
Var D,PD : Single;
begin
 D := 1;
 While D<>0 do
 begin
   PD := D;
   D := D / 2; // потому-что основание системы счисления 2. Но не всегда оно такое. Это тоже определяют
 end;
 ShowMessage(FloatToStr(PD));
end;


 
TSingle   (2006-06-03 07:24) [3]

А как нормальное минимальное найти ?


 
TSingle   (2006-06-03 07:27) [4]

Ну, так и чего она показывает, эта программа ? У меня нет под рукой Дельфи.


 
Alx2 ©   (2006-06-03 08:10) [5]

Пишет
1.40129846432482E-45

Sample page from NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5)
Copyright (C) 1988-1992 by Cambridge University Press. Programs Copyright (C) 1988-1992 by Numerical Recipes Software.
Permission is granted for internet users to make one paper copy for their own personal use. Further reproduction, or any copying of machinereadable
files (including this one) to any server computer, is strictly prohibited. To order Numerical Recipes books or CDROMs, visit website
http://www.nr.com or call 1-800-872-7423 (North America only), or send email to directcustserv@cambridge.org (outside North America).

Переведенный на паскаль пример:


type
  mld = single; // пишем интересующий тип

procedure machar(var ibeta, it, irnd, ngrd, machep, negep,
 iexp, minexp, maxexp: integer; var eps, epsneg, xmin, xmax: mld);
(*Determines and returns machine-specific parameters affecting mlding-point arithmetic. Returned
values include ibeta, the mlding-point radix; it, the number of base-ibeta digits in
the mlding-point mantissa; eps, the smallest positive number that, added to 1.0, is not equal
to 1.0; epsneg, the smallest positive number that, subtracted from 1.0, is not equal to 1.0;
xmin, the smallest representable positive number; and xmax, the largest representable positive
number. See text for description of other returned parameters.*)
var
 i, itemp, iz, j, k, mx, nxres: integer;
 a, b, beta, betah, betain, one, t, temp, temp1, tempa, two, y, z, zero: mld;
begin
 one := 1;
 two := one + one;
 zero := one - one;
 a := one; { Determine ibeta and beta by the method of M. Malcolm}
 repeat
   a := a + a;
   temp := a + one;
   temp1 := temp - a;
 until not (temp1 - one = zero);
 b := one;
 repeat
   b := b + b;
   temp := a + b;
   itemp := trunc(temp - a);
 until not (itemp = 0);
 ibeta := itemp;
 beta := ibeta;
 it := 0; {Determine it and irnd.}
 b := one;
 repeat
   inc(it);
   b := b * beta;
   temp := b + one;
   temp1 := temp - b;
 until not (temp1 - one = zero);
 irnd := 0;
 betah := beta / two;
 temp := a + betah;
 if (temp - a <> zero) then irnd := 1;
 tempa := a + beta;
 temp := tempa + betah;
 if (irnd = 0) and (temp - tempa <> zero) then irnd := 2;
 negep := it + 3; {Determine negep and epsneg.}
 betain := one / beta;
 a := one;
 for i := 1 to negep - 1 do a := a * betain;
 b := a;
 while true do
 begin
   temp := one - a;
   if (temp - one <> zero) then break;
   a := a * beta;
   dec(negep);
 end;
 negep := -negep;
 epsneg := a;
 machep := -it - 3; {Determine machep and eps.}
 a := b;
 while true do
 begin
   temp := one + a;
   if (temp - one <> zero) then break;
   a := a * beta;
   inc(machep);
 end;
 eps := a;
 ngrd := 0; {Determine ngrd.}
 temp := one + eps;
 if (irnd = 0) and (temp * one - one <> zero) then ngrd := 1;
 i := 0; {Determine iexp.}
 k := 1;
 z := betain;
 t := one + eps;
 nxres := 0;
 while true do
 begin
   y := z;
   z := y * y;
   a := z * one; {Check here for the underflow.}
   temp := z * t;
   if (a + a = zero) or (abs(z) >= y) then break;
   temp1 := temp * betain;
   if (temp1 * beta = z) then break;
   inc(i);
   k := k + k;
 end;
 if ibeta <> 10 then begin
   iexp := i + 1;
   mx := k + k;
 end else begin
   iexp := 2;
   iz := ibeta;
   while (k >= iz) do begin
     iz := iz * ibeta;
     inc(iexp);
   end;
   mx := iz + iz - 1;
 end;
 while true do
 begin
   xmin := y;
   y := y * betain;
   a := y * one; {Check here for the underflow.}
   temp := y * t;
   if (a + a <> zero) and (abs(y) < xmin) then begin
     inc(k);
     temp1 := temp * betain;
     if (temp1 * beta = y) and (temp <> y) then begin
       nxres := 3;
       xmin := y;
       break;
     end
   end
   else break;
 end;
 minexp := -k; {Determine maxexp, xmax.}
 if (mx <= k + k - 3) and (ibeta <> 10) then
 begin
   mx := mx + mx;
   inc(iexp);
 end;
 maxexp := mx + minexp;
 irnd := irnd + nxres; {Adjust irnd to reflect partial underflow.}
 if (irnd >= 2) then maxexp := maxexp - 2; {Adjust for IEEE-style machines.}
 i := maxexp + minexp;
 if (ibeta = 2) and (i <> 0) then
   dec(maxexp);
 if (i > 20) then
   dec(maxexp);
 if (a <> y) then
   dec(maxexp, 2);
 xmax := one - epsneg;
 if (xmax * one <> xmax) then
   xmax := one - beta * epsneg;
 xmax := xmax / ((xmin * beta * beta * beta));
 i := maxexp + minexp + 3;
 for j := 1 to i do
 begin
   if (ibeta = 2)
     then xmax := xmax + xmax
   else xmax := xmax * beta;
 end;
end;
var ibeta, it, irnd, ngrd, machep, negep,
iexp, minexp, maxexp: integer; var eps, epsneg, xmin, xmax: mld;
begin
 machar(ibeta, it, irnd, ngrd, machep, negep,
     iexp, minexp, maxexp, eps, epsneg, xmin, xmax);
       writeln("ibeta = ", ibeta, " it = ", it, " irnd=", irnd);
         writeln("ngrd = ", ngrd, " machep = ", machep, " negep=", negep);
           writeln("iexp = ", iexp, " minexp = ", minexp, " maxexp=", maxexp);
             writeln("eps = ", eps, " epsneg = ", epsneg);
               Writeln(" xmin=", xmin, " xmax=", xmax);
end.


Результат для моей машины:
ibeta = 2 - основание системы счисления.
it = 24 - разрядность вещественной мантиссы (3 байта)
irnd=5 - способ округления
ngrd = 0 - количество разрядов "про запас" для  поддержки точности.
machep = -24    ibeta^machep - минимальное число, которое при сложении с единицей дает результат, отличный от единицы.
negep=-25    ibeta^negep - минимальное число, которое при вычитании из единицы дает результат, отличный от единицы.

iexp = 8 - разрядность порядка (1 байт). Итого Single занимает 3+1 = 4 байта
minexp = -126   - минимальное значение порядка
maxexp=127   - максимальное значение порядка

eps =  1.19209289550781E-0007 -  как раз  машинное eps = ibeta^machep
epsneg =  5.96046447753906E-0008

xmax= 1.70141173319264E+0038 - максимальное по абсолютной величине используемое вещественное число = (1&#8722;epsneg)&#215;ibeta^maxexp,

В твоем случае минимальное есть
-1.70141173319264E+0038


 
Alx2 ©   (2006-06-03 08:26) [6]

Еще не проснулся. Нагнал с результатами :(
xmax в два раза больше: 3.4*10^38


 
Alx2 ©   (2006-06-03 08:43) [7]

Все. Нашел ошибку. Вот исправленная табличка:

ibeta = 2 it = 24 irnd=5
ngrd = 0 machep = -24 negep=-25
iexp = 8 minexp = -126 maxexp=128
eps =  1.19209289550781E-0007 epsneg =  5.96046447753906E-0008
xmin= 1.17549435082229E-0038 xmax= 3.40282346638529E+0038

Ошибка в приведенном выше коде (при переводе накололся спросонья. сорри).

Строку
 if (ibeta = 2) and (i <> 0) then
заменить на
 if (ibeta = 2) and (i = 0) then



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2006.07.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.022 c
6-1140518682
Officeman
2006-02-21 13:44
2006.07.02
Передача данных


2-1150390709
Новичок__
2006-06-15 20:58
2006.07.02
Серийный номер HDD


15-1149753417
ProScan
2006-06-08 11:56
2006.07.02
Как посмотреть всё установленное оборудование в XP SP2


2-1150370616
КиТаЯц
2006-06-15 15:23
2006.07.02
Форма из DLL поверх вызвавшего окна


15-1149290295
Копир
2006-06-03 03:18
2006.07.02
Lib.ru запретили





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский