February 01, 2007 Floating-point zeros not caught by comparison | ||||
---|---|---|---|---|
| ||||
I'm having a problem with an if statement not catching some floating-point zeros. I know that there are 9 values in the array, but only 7 are found by the if and outputted by the debug statement. If I remove the if statement and the code in its block, all 9 of the zeros are printed by the debug statement. Does anyone have any idea what might be the problem? Thanks, JonathanC Code: ------------------------------------------------------------------------------------------ uint zeros = 0; real test = .01; uint size = X.Rows; for (uint i = 0; i < size; i++) { real r = X.Data[i]; debug (calcXHI) writefln("i:", i, ", r:", r); if (std.math.abs(r) <= test) { zeros++; size--; for (j = i + 1; j < size; j++) { X.Data[j - 1] = X.Data[j]; } } } |
February 01, 2007 Re: Floating-point zeros not caught by comparison | ||||
---|---|---|---|---|
| ||||
Posted in reply to JonathanC | JonathanC wrote:
> I'm having a problem with an if statement not catching some floating-point zeros. I know that there are 9 values in the array, but only 7 are found by the if and outputted by the debug statement. If I remove the if statement and the code in its block, all 9 of the zeros are printed by the debug statement.
>
> Does anyone have any idea what might be the problem?
>
> Thanks,
> JonathanC
>
> Code:
> ------------------------------------------------------------------------------------------
> uint zeros = 0;
> real test = .01;
> uint size = X.Rows;
> for (uint i = 0; i < size; i++)
> {
> real r = X.Data[i];
> debug (calcXHI) writefln("i:", i, ", r:", r);
> if (std.math.abs(r) <= test)
> {
> zeros++;
> size--;
> for (j = i + 1; j < size; j++)
> {
> X.Data[j - 1] = X.Data[j];
> }
> }
> }
So you're removing the zeros by copying the part of the array after every zero one place forward?
First of all, you should probably decrease 'size' after the inner loop to preserve the last element.
It looks like you forgot to also decrease i when you do that, so if there are two consecutive zeros you miss the second one.
So that gets you this (modified to make X a regular array):
---
import std.stdio;
import std.math;
void main() {
float[] X = [ 0f, 1, 2, 0, 0, 3, 4, 5, 0, 6, 7, 0, 0, 8];
writefln(X);
uint zeros = 0;
real test = .01;
uint size = X.length;
for (uint i = 0; i < size; i++)
{
real r = X[i];
debug (calcXHI) writefln("i:", i, ", r:", r);
if (std.math.abs(r) <= test)
{
zeros++;
for (size_t j = i + 1; j < size; j++)
{
X[j - 1] = X[j];
}
size--;
i--;
}
}
writefln(X[0 .. size]);
}
---
Also, this code might be more efficient: (will only copy values once at most)
---
import std.stdio;
import std.math;
void main() {
float[] X = [ 0f, 1, 2, 0, 0, 3, 4, 5, 0, 6, 7, 0, 0, 8];
writefln(X);
uint zeros = 0;
real test = .01;
uint size = X.length;
// k is the next element to inspect.
// i is the next location to copy to.
// loop ends when k >= X.length (not size) because later elements
// aren't moved anymore.
for (uint i = 0, k = 0; k < X.length; k++)
{
real r = X[k];
debug (calcXHI) writefln("i:", i, ", k:", k, ", r:", r);
if (std.math.abs(r) <= test)
{
zeros++;
size--;
}
else
{
// copy next element (can be conditional on (zeros > 0) or,
// if you prefer, (i != k)
X[i] = r;
i++;
}
}
writefln(X[0 .. size]);
}
---
|
Copyright © 1999-2021 by the D Language Foundation