Текущий архив: 2006.07.02;
Скачать: CL | DM;
Вниз
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−epsneg)×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;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.009 c