| Thread overview | ||||||
|---|---|---|---|---|---|---|
|
April 11, 2009 weird behavior for machine epsilon in float, double and real | ||||
|---|---|---|---|---|
| ||||
So, for the following code, I get something I think is a little off. I get the same value for all three variable types. I'm kind of new to this, but I would think that a 32 bit would give me a different "smallest value" than a 64 bit or 80 bit (if real even evaluates to 80 bit on my machine).
What am I doing wrong, or is this a bug?
import std.stdio;
void main() {
//Find Machine Epsilon:
double ep = 1.0;
double n = 1.0;
while (ep + n != n) {
ep = ep / 2;
}
writefln(ep);
real epr = 1.0;
real nr = 1.0;
while (epr + nr != nr)
epr = epr / 2;
writefln(epr);
float epf = 1.0;
float nf = 1.0;
while (epf + nf != nf)
epf = epf / 2;
writefln(epr);
}
| ||||
April 11, 2009 Re: weird behavior for machine epsilon in float, double and real | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrew Spott | Andrew Spott:
> import std.stdio;
> [...]
This is the same code of yours, a bit refactored:
import std.stdio: writefln;
template Tuple(T...) { alias T Tuple; }
void computeEpsilon(T)() {
T ep = 1;
T n = 1;
while ((ep + n) != n)
ep /= 2;
writefln("%.30f type: %s", ep, typeid(T));
}
void main() {
foreach (T; Tuple!(float, double, real))
computeEpsilon!(T)();
}
Bye,
bearophile
| |||
April 11, 2009 Re: weird behavior for machine epsilon in float, double and real | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrew Spott | Hello Andrew, > So, for the following code, I get something I think is a little off. > I get the same value for all three variable types. I'm kind of new to > this, but I would think that a 32 bit would give me a different > "smallest value" than a 64 bit or 80 bit (if real even evaluates to 80 > bit on my machine). > > What am I doing wrong, or is this a bug? > This is a classic case of the optimizer getting in your way by doing all the math in the FPU (the other classic cases is it noting that as long as ep!=0, ep+n "can't" equal n). If you are on x86 than the only type the FPU uses inside is 80bit-real. > import std.stdio; > > void main() { > > //Find Machine Epsilon: > > double ep = 1.0; > double n = 1.0; > while (ep + n != n) { > ep = ep / 2; > } > writefln(ep); > > real epr = 1.0; > real nr = 1.0; > while (epr + nr != nr) > epr = epr / 2; > writefln(epr); > > float epf = 1.0; > float nf = 1.0; > while (epf + nf != nf) > epf = epf / 2; > writefln(epr); > } | |||
April 11, 2009 Re: weird behavior for machine epsilon in float, double and real | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrew Spott | Andrew Spott wrote:
> So, for the following code, I get something I think is a little off.
> I get the same value for all three variable types. I'm kind of new
> to this, but I would think that a 32 bit would give me a different
> "smallest value" than a 64 bit or 80 bit (if real even evaluates to
> 80 bit on my machine).
>
> What am I doing wrong, or is this a bug?
The expression: (ep + n != n) is evaluated at 80 bit precision, regardless of the size of its operands. The idea is that the floating point sizes only specify a minimum precision, and the compiler (where it makes sense) can use a larger precision to do constant folding and/or for intermediate values.
If you need the epsilon values, use float.epsilon, double.epsilon, and real.epsilon.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply