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
}
} 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
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
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.
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
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.
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 ....
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
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
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...
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)
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.
"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
>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) This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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...
|
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"...
|
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).
...
|
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,"...
|
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...
|
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...
|
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...
|
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...
|
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
|
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...
|
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...
|
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,...
|
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,...
|
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...
|
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...
|
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,...
|
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...
| |