473,405 Members | 2,282 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

sign_command (e.g not_negative) missing(?) in C++ (/C)

I am not an expert on C++(/C), but also not a complete beginner.

I was writing a faster cos (and sin) approximation based on
precalculated data (with some success) when I discovered that going
from double to int is quite expensive, so maybe a cos/sin approximation
without precalculation would be better (faster).

Nevertheless I (still) needed to find out where on the unit-cirkle the
angle
(a double (v) from 0 to 2PI) was. And I looked for a command like

int not_negative(double d) // return 1 if d==(+)0.0, d==1.2 aso else 0
(and int not_positive(double d) // return 1 if d==-0.0 d==-1.6 (else
0))

My guess is that such a command could be made real fast (with some
bit-mangleling - am I wrong here?) I do not know how dobbles looks in
bits
and if it is the same on all machines, but I think it could be made
fast ....

If I had a fast command like this (and gcc/g++ with -O3 does not make
the
comparison x>=0 fast - maybe the answer is that that is the real
problem
,but if it is possible to make a fast function without a compare the
language would signal that this works without a compare and therefore
is faster)

it would be possible to write something like :
Depending on how fast the function is this might he faster than a
binary
search on v.

Does anybody has some comments on this ?

double cos(double v)
{
:rerun
v=fabs(v)-(2.0*PI);
int part = 0;

part=part + not_negative(v); // v was bigger than 2PI
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);

switch (part)
{
case 0 : return something for case0;
case 1 : return something for case1;
case 2 : return something for case2;
case 3 : return something for case3;
case 4 : return something for case4;
case 5 : return something for case5;
case 6 : return something for case6;
case 7 : return something for case7;
case 8 : x is not in [0;2PI].
// This was not a "part" of the deal but
// fix x and goto rerun
}
}

Sep 6 '05 #1
13 1516
tmartsum wrote:
I am not an expert on C++(/C), but also not a complete beginner.

I was writing a faster cos (and sin) approximation based on
precalculated data (with some success) when I discovered that going
from double to int is quite expensive, so maybe a cos/sin approximation
without precalculation would be better (faster).

Nevertheless I (still) needed to find out where on the unit-cirkle the
angle
(a double (v) from 0 to 2PI) was. And I looked for a command like

int not_negative(double d) // return 1 if d==(+)0.0, d==1.2 aso else 0
(and int not_positive(double d) // return 1 if d==-0.0 d==-1.6 (else
0))

My guess is that such a command could be made real fast (with some
bit-mangleling - am I wrong here?) I do not know how dobbles looks in
bits
and if it is the same on all machines, but I think it could be made
fast ....

The solution would not be portable. But, anyhow, take a look at your
compiler implementation details about the double format, which will be
formed by exponent and mantissa, locate the sign bit in the mantissa,
make a non-portable implementation dependent be-careful-with-it method
to test it.
An be ready to change it as soon as you discover better ways (such as
division to discover how many times PI/4.0 is contained in a double)

Zara
Sep 6 '05 #2

Zara skrev:

The solution would not be portable. But, anyhow, take a look at your
compiler implementation details about the double format, which will be
formed by exponent and mantissa, locate the sign bit in the mantissa,
make a non-portable implementation dependent be-careful-with-it method
to test it.
An be ready to change it as soon as you discover better ways (such as
division to discover how many times PI/4.0 is contained in a double) Zara


Thanks for the answer - It was my guess that it would not be portable.
(And I want to write portable C++ (or in this case it is just C)

My subject was also : "sign_command missing(?) in C++" hence the
compiler would probably know how to do this quick for a given platform,
but I can make no fast algoritm unless I write C++ that creates C++
(Which I am not fond of.)

PS : Something I should have written first :
int part = static_cast<int> (floor(v*(1/(2.0*PI)*8)));

is not (as I remember it) performing good. Both the cast and floor are
expensive. I was considering not using pre_calculated data of 2
reasons.
1) The lookup with a possible cache-miss
2) The cast from double to int

Sep 6 '05 #3
tmartsum wrote:
My subject was also : "sign_command missing(?) in C++" hence the
compiler would probably know how to do this quick for a given platform,
but I can make no fast algoritm unless I write C++ that creates C++
(Which I am not fond of.)
The sign command should be

inline bool not_negative(double d) {return d>=0.0;}

This is the most efficient way, if we honour portability.

PS : Something I should have written first :
int part = static_cast<int> (floor(v*(1/(2.0*PI)*8)));

is not (as I remember it) performing good.


This one is sub-optimal, it is in fact redundant. *IF* you guarantee
that v >=0.0, then the following expression is enough:

int part = static_cast<int> (v*(1/(2.0*PI)*8));

Because casting form real types to integer types is done rounding
towards zero.

Sep 6 '05 #4

tmartsum schreef:
My guess is that a [sign] command could be made real fast (with some
bit-mangleling - am I wrong here?) I do not know how dobbles looks in
bits and if it is the same on all machines, but I think it could be
made fast ....

If I had a fast command like this (and gcc/g++ with -O3 does not make
the comparison x>=0 fast - maybe the answer is that that is the real
problem


It is. The check d>=0.0 should be optimized by a peephole optimizer.
This is a common form of optimizing: take a fixed instruction sequence
from the unoptimized code and replace it by a better form.

HTH,
Michiel Salters

Sep 6 '05 #5
tmartsum wrote:
int part = static_cast<int> (floor(v*(1/(2.0*PI)*8)));

is not (as I remember it) performing good. Both the cast and
floor are expensive.


If you're on x86, you can try the FISTTP truncating integer store
instruction to avoid the gymnastics a compiler is forced into
generating from the cast because it cannot rely on the FPU being set
to any particular rounding mode. That would mean a line of inline
assembly which is nonportable across compilers in addition to across
platforms. Intel's instruction set reference is at
http://www.intel.com/design/pentium4/manuals/253666.htm .

As a side note, you may want to evaluate floating-point constant
expressions yourself as a compiler is not allowed to do that.
Martin

--
Quidquid latine dictum sit, altum viditur.
Sep 6 '05 #6
inline bool not_negative(double d) {return d>=0.0;}

Yes - but compiler (g++ -O3) does not make it fast enough.
I will look into it - but it uses a

fucomp
and
fnstsw

which are not high performing.
I will find out what to write and then mail it to them.

(And I use the cast just for the example - to show the cast and get rid
of a warning - warnings are half errors)

As I mention later a actually use lrint ....

Sep 6 '05 #7
Hello Mr. Michiel Salters

Thanks for your answer. I will not try to figure out some smart
assembly code and mail it to gcc (if I can create anything usefull).

What I was considering was if it was more idiomatic to have
such a function it in math.h. There would be at least two good reasons.

1) Avoid thinking thinking about nan (like fabs does).
(*This might be a reason for the compiler to do the compare.
If v was nan it must return false*)

2) Force compile-writes to think about this special case and make them
optimize the function bitwise.

Timing on my cpu indicates that this switch would indead be faster that
a binary search for 8 cases if this function was lightning fast.

So I was thinking if I could have overlooked it. But I will make a
peephole-paterne unless I stumble upon anther solution. Thanks.

Thorbjørn Martsum

Sep 6 '05 #8
Hi Martin Eisenberg

Acually I use lrint. It expands to FISTTP. =)
Quite fast - and a lot faster than the cast - but not fast fast....

regards
Thorbjørn

Sep 6 '05 #9
Ben
tmartsum wrote:
inline bool not_negative(double d) {return d>=0.0;}

Yes - but compiler (g++ -O3) does not make it fast enough.
I will look into it - but it uses a

fucomp
and
fnstsw

which are not high performing.
I will find out what to write and then mail it to them.

(And I use the cast just for the example - to show the cast and get rid
of a warning - warnings are half errors)


....the cast does not solve the "half-error", it merely makes the warning
go away.

Ben
--
I'm not just a number. To many, I'm known as a String...
Sep 7 '05 #10
The cast implies that "I think I know what I am doing" on a critical
spot.
I hate working in projects where warnings are accepted.

I do not consider the assignment as an error, but wheather it is or not
is a matter of view and philosophy and far away from the problem I with
NO FAST WAY TO GET THE SIGNBIT IN C/C++

(unless you cheat and asumes that double and float follwos IEEE 754)

Sep 7 '05 #11
The function I was searching for was signbit in math.h
(Are there any (real) experts reading this forum?)

I found out reporting an error to g++ in the following code:
int is_not_positive(double v)
{
return ((reinterpret_cast<unsigned int*>(&v)[1]) >> 31);
}

There is no union so there is "c++" standard does not guarantee it will
work however there is no reason it should not work on x86.
(A union should be used and it is just as fast - the compiler can
optimize it)
But beside saying that it was both fixed in newer version and the code
was bad (which I knew) they informed about signbit.

Sep 10 '05 #12
"tmartsum" <tm******@gmail.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
The function I was searching for was signbit in math.h
(Are there any (real) experts reading this forum?)
Yes, I knew about it. But:

a) it's a C99 function, soon to appear in TR1 but not
officially available to C++

b) you've been so preoccupied with performance in the small
that I didn't feel like defending whether the function can
be done in one instruction or three.
I found out reporting an error to g++ in the following code:
int is_not_positive(double v)
{
return ((reinterpret_cast<unsigned int*>(&v)[1]) >> 31);
}
Why shift right when all you need is zero/nonzero?
There is no union so there is "c++" standard does not guarantee it will
work however there is no reason it should not work on x86.


Except that the byte order is wrong.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com

Sep 10 '05 #13
>it's a C99 function, soon to appear in TR1 but not officially available to C++

a) Ok maybe I was a bit rude - and maybe you are right that it is not
C++ however the gcc people told me to use it. (Normally all C is also
C++ or will be it later =) )
you've been so preoccupied with performance in the small that I didn't feel like defending whether the function can be done in one instruction or three.
b) OK - I may have been a little to interessetet in speed and maybe not
been that friendly to all replys. (When persons has talked about a
completly different than the problem or not understood a bit of it)
Why shift right when all you need is zero/nonzero?
c) Actually I need the zero/one. I want to do some calculations on a
double and meanwhile sometimes call sign and add it to a variabel (not
excatly the way done in my first post - but similar). Then later I will
switch the sum of serveral signs.

Getting a zero/one version from the nonzero/zero version is not hard.
(!! in front could be considered) but another option is :

const int signbit_shift = round(log2(signbit(-1.0)))
inline /* maybe a macro is better */ is_not_positive(double v)
{
if (signbit(-1.0) == 1) // compilers should be able to eliminate the
if
return signbit(v);
extern const int signbit_shift;
return signbit(v) << signbit_shift
}
Except that the byte order is wrong.

?? not understood - it worked on my machine ... But many things are
wrong with it - intsize must also be 32 doublesize=64 .... (could
maybe be fixed with macros) - but then there is the fact that
optimizeres can be tricked by it. (And if doubles are not IEEE 754
standard that is also wrong)

Sep 10 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Steven T. Hatton | last post by:
If you happen to have Accelerated C++ by Koenig and Moo, and haven't gotten around to reading it, I suggest you count the pages between page 18 and page 51. I came up with zero. This is very...
7
by: Corepaul | last post by:
Missing Help Files When I enter "recordset" as the keyword and search the Visual Basic Help index, I get many topics of interest in the resulting list. But there isn't any information available...
102
by: Skybuck Flying | last post by:
Sometime ago on the comp.lang.c, I saw a teacher's post asking why C compilers produce so many error messages as soon as a closing bracket is missing. The response was simply because the compiler...
0
by: kris | last post by:
hi can any one help me out, i have written a code for Word Indexing using Dll's i think this is an incomplete code for WORD INDEX. I had encountered this error "Error! No index entries found"...
17
by: Justin Emlay | last post by:
I'm hopping someone can help me out on a payroll project I need to implement. To start we are dealing with payroll periods. So we are dealing with an exact 10 days (Monday - Friday, 2 weeks). ...
2
by: jodyblau | last post by:
I have noticed that when I move my database onto a different computer, I often get a message about some reference missing. So I go into the reference list, and find the one that says "Missing,"...
0
by: youth | last post by:
I am trying to bind the DB2 utlities to a new database that was created by our DBAs. Each time I try I get the following: db2ajgrt.bnd - No errors db2clish.bnd - 13 errors all for missing...
5
by: le0 | last post by:
Hello guys, Im really having a hard time doing this, I have a record set with the ItemNo field with the data type as Text. In the record that I have, I want to find the missing number in the...
1
by: BobPaul | last post by:
I'm following code out of a howto book and this is really bugging me. This header file was created by VStudio 6.0 when I did a "Right Click: Add Member Function" CLine is a class I wrote (per the...
3
by: Fred Chateau | last post by:
Still working on my XML DataSet... Having moved on past difficult and complex problems, resolved with the assistance of everyone here, I find myself facing yet another problem. My XML document...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.