set double array to 0.0

W

Wei Zhou

Carson said:
Hi ,

Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

Carson
In my computer that's correct!
 
C

Carson

Hi ,

Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

Carson
 
T

Tom St Denis

Carson said:
Hi ,

Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

Um try something along these lines

double myarray[SIZE], tmp;

tmp = 0.0;
memcpy(myarray, &tmp, sizeof(double));
memcpy(myarray+1, &tmp, sizeof(double));
memcpy(myarray+2, myarray, sizeof(double)*2);
memcpy(myarray+4, myarray, sizeof(double)*4);
memcpy(myarray+8, myarray, sizeof(double)*8);
memcpy(myarray+16, myarray, sizeof(double)*16);
.... until you cover SIZE

Tom
 
C

Christian Bau

"Carson said:
Hi ,

Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

Use a "for" loop. Works every time.
 
S

SM Ryan

# Hi ,
#
# Is there a very efficient way to set a double array to 0 ?
# (I have tried memset, but the result doesn't look correct.)

Most CPUs nowadays allow all zero bits as a real zero. Did you give memset
the right length?
double r[N];
memset(r,0,N*sizeof(double));

There's a trick you can play with some implementations of memcpy.

Otherwise you have to set with some kind loop.
 
C

CBFalconer

Carson said:
Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

No, not and have the results meet the standards. Tou need
something like:

for (i = 0; i < size; i++) array = 0.0;
 
J

Jack Klein

Hi ,

Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

Carson

If you are defining the array, you can merely do this:

double d [SIZE] = { 0 };

....and this will initialize each and every member to 0.0.

On the other hand, if you have a malloc'ed array, or you have an array
that has unknown data in it that needs to be cleared to 0.0, a for
loop is probably best if the array is small. If it is very large,
this might be faster:

d [0] = 0; /* or 0.0, if you prefer */
memmove(d + 1, d, sizeof(double) * (SIZE - 1));

Using memmove() instead of memcpy() guarantees defined behavior even
though the source and destination areas overlap.

You would need to run timing tests on your particular
compiler/hardware combination to find out at what array size, if any,
the memmove() version becomes faster and by how much.
 
K

Keith Thompson

Carson said:
Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

If you called memset with the right arguments, I would expect you to
see 0.0 in all entries on almost all systems. (Did you remember to
multiply the length by sizeof(double)?) But the standard doesn't
guarantee that 0.0 is represented as all-bits-zero, so using memset
isn't strictly portable.

Probably the best solution is the simplest:

for (i = 0; i < LEN; i ++) {
arr = 0.0;
}

See whether that's fast enough before you try something more
complicated.
 
S

S.Tobias

Jack Klein said:
d [0] = 0; /* or 0.0, if you prefer */
memmove(d + 1, d, sizeof(double) * (SIZE - 1));

IMHO it won't work, unless I'm missing something very obvious.
(Values d[1], d[2]... are undetermined, and are copied
into positions d+2, d+3...)
 
T

Thomas Matthews

Tom said:
Carson wrote:

Hi ,

Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)


Um try something along these lines

double myarray[SIZE], tmp;

tmp = 0.0;
memcpy(myarray, &tmp, sizeof(double));
memcpy(myarray+1, &tmp, sizeof(double));
memcpy(myarray+2, myarray, sizeof(double)*2);
memcpy(myarray+4, myarray, sizeof(double)*4);
memcpy(myarray+8, myarray, sizeof(double)*8);
memcpy(myarray+16, myarray, sizeof(double)*16);
... until you cover SIZE

Tom

I believe that a simple "for" loop would be much
easier to understand and probably more efficient
{since the function call overhead is removed).

unsigned int i;
for (i = 0; i < SIZE; ++i)
{
myarray = 0.0;
}


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
J

Jack Klein

Jack Klein said:
d [0] = 0; /* or 0.0, if you prefer */
memmove(d + 1, d, sizeof(double) * (SIZE - 1));

IMHO it won't work, unless I'm missing something very obvious.
(Values d[1], d[2]... are undetermined, and are copied
into positions d+2, d+3...)

But they are not undetermined. memmove(), as opposed to memcpy(), is
specified to copy properly when the source and destination areas
overlap, as in this case. If they overlap, it is guaranteed to read
and copy the old value of each byte before overwriting the byte with
its new value.

So the first byte of d [1] will have the value of the first byte of d
[0] before it is copied into the first byte of d [2], and so on. This
is perfectly legal and has a completely defined result.

On the other hand, memcpy() has undefined behavior if the source and
destination areas overlap. There is no guarantee that the first byte
of d [0] is copied into the first byte of d [1] before that byte in
turn is copied into the first byte of d [2].
 
B

Barry Schwarz

Jack Klein said:
d [0] = 0; /* or 0.0, if you prefer */
memmove(d + 1, d, sizeof(double) * (SIZE - 1));

IMHO it won't work, unless I'm missing something very obvious.
(Values d[1], d[2]... are undetermined, and are copied
into positions d+2, d+3...)

But they are not undetermined. memmove(), as opposed to memcpy(), is
specified to copy properly when the source and destination areas
overlap, as in this case. If they overlap, it is guaranteed to read
and copy the old value of each byte before overwriting the byte with
its new value.

It is true that memmove supports overlapping operands.
So the first byte of d [1] will have the value of the first byte of d
[0] before it is copied into the first byte of d [2], and so on. This
is perfectly legal and has a completely defined result.

Unless something changed from n869, this conclusion is wrong. From
7.21.2.2-2: "Copying takes place as if the n characters from the
object pointed to by s2 are first copied into a temporary array of n
characters that does not overlap the objects pointed to by s1 and s2,
and then the n characters from the temporary array are copied into the
object pointed to by s1."

Since memmove acts as if the source bytes are copied first, they will
have undetermined values. Since they are not being evaluated, I don't
know if the behavior is undefined.


<<Remove the del for email>>
 
D

Dag Viken

Keith Thompson said:
Carson said:
Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

If you called memset with the right arguments, I would expect you to
see 0.0 in all entries on almost all systems. (Did you remember to
multiply the length by sizeof(double)?) But the standard doesn't
guarantee that 0.0 is represented as all-bits-zero, so using memset
isn't strictly portable.

Probably the best solution is the simplest:

for (i = 0; i < LEN; i ++) {
arr = 0.0;
}

See whether that's fast enough before you try something more
complicated.


I agree. I just tested this code with VC7 and the loop was reduced to a 'REP
STOSD' instruction, which clearly is faster than calling memset. In debug
mode the generated code was terrible, but that's OK.

Dag
 
T

Tom St Denis

Dag said:
Keith Thompson said:
Carson said:
Is there a very efficient way to set a double array to 0 ?
(I have tried memset, but the result doesn't look correct.)

If you called memset with the right arguments, I would expect you to
see 0.0 in all entries on almost all systems. (Did you remember to
multiply the length by sizeof(double)?) But the standard doesn't
guarantee that 0.0 is represented as all-bits-zero, so using memset
isn't strictly portable.

Probably the best solution is the simplest:

for (i = 0; i < LEN; i ++) {
arr = 0.0;
}

See whether that's fast enough before you try something more
complicated.


I agree. I just tested this code with VC7 and the loop was reduced to a
'REP STOSD' instruction, which clearly is faster than calling memset. In
debug mode the generated code was terrible, but that's OK.


OT but...

GCC will do a fairly awesome job with memcpy/memset functions. When the
goal is speed it will usually unroll/inline the function call. The GCC
3.4.1 tree is even smart enough to rotate free regs e.g.

movl (%esi),%eax
movl %eax,(%edi)
movl 4(%esi),%ebx
movl %ebx,4(%edi)
movl 8(%esi),%ecx
movl %ecx,8(%edi)
// etc...

Tom
 
C

Christian Bau

Jack Klein said:
Jack Klein said:
d [0] = 0; /* or 0.0, if you prefer */
memmove(d + 1, d, sizeof(double) * (SIZE - 1));

IMHO it won't work, unless I'm missing something very obvious.
(Values d[1], d[2]... are undetermined, and are copied
into positions d+2, d+3...)

But they are not undetermined. memmove(), as opposed to memcpy(), is
specified to copy properly when the source and destination areas
overlap, as in this case. If they overlap, it is guaranteed to read
and copy the old value of each byte before overwriting the byte with
its new value.

memmove () behaves exactly as if you malloc'ed a block of memory that is
big enough, memcpy from src to that buffer and then memcpy back from
that buffer to dst, then free'ing the block.

If memmove worked as you describe it then I would pray that it is
removed from the C Standard Library.
 
K

Keith Thompson

Jack Klein said:
Jack Klein said:
d [0] = 0; /* or 0.0, if you prefer */
memmove(d + 1, d, sizeof(double) * (SIZE - 1));

IMHO it won't work, unless I'm missing something very obvious.
(Values d[1], d[2]... are undetermined, and are copied
into positions d+2, d+3...)

But they are not undetermined. memmove(), as opposed to memcpy(), is
specified to copy properly when the source and destination areas
overlap, as in this case. If they overlap, it is guaranteed to read
and copy the old value of each byte before overwriting the byte with
its new value.

Um, no. I don't think "properly" means what you think it means in
this context.

I've seen Unix man pages that say something like:

The memmove() function copies n bytes from memory areas s2
to s1. Copying between objects that overlap will take place
correctly. It returns s1.

without defining what "correctly" means. If you're depending on a
description like that, I can see why you might think it copies
byte-by-byte.

Here's what the standard says (C99 7.21.2.2):

The memmove function copies n characters from the object pointed
to by s2 into the object pointed to by s1. Copying takes place as
if the n characters from the object pointed to by s2 are first
copied into a temporary array of n characters that does not
overlap the objects pointed to by s1 and s2, and then the n
characters from the temporary array are copied into the object
pointed to by s1.

I've seen a trick similar to what you suggest, but using memcpy() or a
similar function -- but it works only if copying is done from low to
high addresses, something not guaranteed by the standard.

(In real life, memmove() is likely to check whether the source and
destination overlap, choosing an order that avoids problems. There's
no portable way to do that without invoking undefined behavior, but
the memmove() implementation is free to use non-portable tricks.)
 
M

Mabden

(In real life, memmove() is likely to check whether the source and
destination overlap, choosing an order that avoids problems. There's
no portable way to do that without invoking undefined behavior, but
the memmove() implementation is free to use non-portable tricks.)

In any case, you are better off knowing your own data, and doing the
appropriate copying.

Has anyone done speed checks for mallocing a new chunk and copying the
correct data versus a memmove?

Who even does memmove? It sounds like sloppy programming to me. I mean does
the memory overlap or not?! If you don't know, why are you copying into it?
 
M

Michael Mair

Hiho,

In any case, you are better off knowing your own data, and doing the
appropriate copying.

Has anyone done speed checks for mallocing a new chunk and copying the
correct data versus a memmove?

Who even does memmove? It sounds like sloppy programming to me. I mean does
the memory overlap or not?! If you don't know, why are you copying into it?

Hmmm, memmove() might be more efficient than everything you can come up
with. A naive way of implementing it is to calculate the overlap and
memcopy() just the highest non-critical number of bytes -- which might
lead to memcopy()ing all in one go. However, the system you are working
with might be in favor of a different way of doing it, say getting the
bytes to be copied up or down to a multiple of a certain number or even
more weird things, incorporating special tricks memcopy() does not
employ because they cost a couple of cycles too much but are exactly
the right thing here, etc.
So, memmove() probably is faster than repeated calls to memcopy().

Why someone might want to use it? Imagine having an array of structures.
You are quite happy with that array, need it to be an array because
a linked list or even an index array for a linked list is too slow for
your purposes. Then comes up one small nasty case where you have to
insert something into your array instead of appending it. You know there
will be only this one case, so you decide to stay with the array data
structure.
I, for one, would just memmove() the back end of the used data structure
to make room for my new entry -- provided the array is big enough, of
course. And I would not die regretting that as a programming sin.


Cheers,
Michael
 
F

Flash Gordon

In any case, you are better off knowing your own data, and doing the
appropriate copying.

If you know the regions overlap them using memmove IS doing the
appropriate copying.
Has anyone done speed checks for mallocing a new chunk and copying the
correct data versus a memmove?

I doubt it.
Who even does memmove? It sounds like sloppy programming to me. I mean
does the memory overlap or not?! If you don't know, why are you
copying into it?

You use memmove when you KNOW the regions overlap, not just when it is
possible they overlap. One instances when you want to use memmove is
deleting from the middle of an array my shifting all the data back.

I do use memmove in some of my code because I do copying between regions
I know overlap.
 
M

Mabden

Michael Mair said:
it?

Hmmm, memmove() might be more efficient than everything you can come up
with. A naive way of implementing it is to calculate the overlap and
memcopy() just the highest non-critical number of bytes -- which might
lead to memcopy()ing all in one go. However, the system you are working
with might be in favor of a different way of doing it, say getting the
bytes to be copied up or down to a multiple of a certain number or even
more weird things, incorporating special tricks memcopy() does not
employ because they cost a couple of cycles too much but are exactly
the right thing here, etc.
So, memmove() probably is faster than repeated calls to memcopy().

But why am I overlapping my data copies?
Why someone might want to use it? Imagine having an array of structures.
You are quite happy with that array, need it to be an array because
a linked list or even an index array for a linked list is too slow for
your purposes. Then comes up one small nasty case where you have to
insert something into your array instead of appending it. You know there
will be only this one case, so you decide to stay with the array data
structure.
I, for one, would just memmove() the back end of the used data structure
to make room for my new entry -- provided the array is big enough, of
course. And I would not die regretting that as a programming sin.

Well, I see where you are coming from now, but I find it hard to believe an
index array can be very time consuming on modren computers. I suppose if you
had thousands of pointers, but then you would want a linked-list, wouldn't
you? And by then, you'd want an ISAM structure or something.

My point was, if it's small and known, you might be better off using a for
loop or two memcopy's, and if it's big enough then a memmove() is
inappropriate because you should be using something better.

Either way the programmer should control what happens. However, I have been
mistaken before.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,146
Messages
2,570,831
Members
47,374
Latest member
anuragag27

Latest Threads

Top