LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-28-2009, 09:12 PM   #1
CoderMan
Member
 
Registered: Jan 2009
Location: Gemini Capsule 25164
Distribution: Gentoo
Posts: 375
Blog Entries: 24

Rep: Reputation: 43
C++ Maximum values and global constants


Hi. I'm programming a small C++ program. I put in two global constants, like so:

Code:
// variable names have been changed to protect the guilty
const unsigned long int HIGHEST_VAL = 0 - 1;
const unsigned long int SECOND_HIGHEST_VAL = 0 - 2;
The idea is that HIGHEST_VAL is always equal to the largest unsigned long int number, and that SECOND_HIGHEST_VAL... you get the picture. But would these lines have the desired effect when compiled on all systems with any size of a long int? It works this way on two x86 and amd64 systems, but I'm a little suspicious because, I would assume, "0 - 1" is evaluated before it is assigned, and so maybe some system might put in, for example, the max value of a 32 bit number into a 64 bit variable.

[Edit: I always compile with g++, though I suppose other compilers would be relevant to the discussion.]

Last edited by CoderMan; 09-28-2009 at 09:13 PM.
 
Old 09-28-2009, 09:30 PM   #2
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
limits.h provides constants for these values. Specifically, look at ULONG_MAX. This quick test worked for me:
Code:
#include <limits.h>
#include <iostream>

using namespace std;

int main(int argc,char **argv){
    cout << ULONG_MAX << endl;
}
 
Old 09-28-2009, 11:15 PM   #3
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
or
#define HIGHEST_VAL (long long)pow(2, (char)(sizeof(unsigned) * 8))
 
Old 09-29-2009, 12:23 AM   #4
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
Quote:
Originally Posted by smeezekitty View Post
or
#define HIGHEST_VAL (long long)pow(2, (char)(sizeof(unsigned) * 8))
Why are you casting the 2nd argument to type char? I also don't believe sizeof(unsigned) is valid.

Specifically, I don't seem to get the right answers from that method:
Code:
#include <iostream>
#include <cmath>
#include <limits.h>

using namespace std;

#define HIGHEST_VAL (long long)pow(2, (char)(sizeof(unsigned)*8))

int main(int argc,char **argv){
    cout << HIGHEST_VAL << endl;
    cout << ULONG_MAX << endl;
}
gives:
Code:
4294967296
18446744073709551615
 
Old 09-29-2009, 12:24 AM   #5
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
no,
that gets the value of an integer
use
#define HIGHEST_VAL (long long)pow(2, (char)(sizeof(unsigned long)*8))
 
Old 09-29-2009, 12:32 AM   #6
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
Keep in mind that your code will require the system to perform a pow() on each use of HIGHEST_VAL. Fortunately, the multiplication is likely to be optimized out. In any case, the portable/standard way to do this is via limits.h. Is there any situation where your macro is the optimal case? (I'm also still not sure what the typecast to char is for. In fact, I would think it would break things when a char overflows...)
 
Old 09-29-2009, 12:35 AM   #7
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
it wouldnt overflow unless the var is bigger then 128bits
i once encountered a non standard compiler
that had no limits.h but did have a pow function
 
Old 09-29-2009, 12:43 AM   #8
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
Valid point, but if you're lacking limits.h, you can always go for left-shift operator.

Also: pow only returns a double, powl (which is non-standard) would be needed for longs. (And you need to subtract 1 from your values to get the maximum that can be stored.)

So lacking limits.h, you could always do:
Code:
#define ULONG_MAX ((unsigned long)1<<(8*sizeof(unsigned long))-1)
Generally, a left-shift operator is much faster than a pow() operation.
 
Old 09-29-2009, 12:47 AM   #9
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
i always used pow but << would be faster
 
Old 09-29-2009, 04:10 AM   #10
cppmyths
LQ Newbie
 
Registered: Sep 2009
Posts: 13

Rep: Reputation: 1
Quote:
Originally Posted by smeezekitty View Post
it wouldnt overflow unless the var is bigger then 128bits
i once encountered a non standard compiler
that had no limits.h but did have a pow function
Seeing as this is C++ did it not have limits no ".h", also long long is non standard (C++). Then there is the fact the 8 is to represent the CHAR_BIT yet that is not defined as the size.

If I had to go a platform specific way with made some assumptions personally this would be my choice
Code:
const unsigned long ULONG_MAX_I_DO_NOT_HAVE_LIMITS(~0ul);

Matir your code will just set the highest bit to one and then negate one which is not what is wanted.

Actually it will not do that, I wonder if anyone can see what it will do?

Last edited by cppmyths; 09-29-2009 at 04:45 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to check the cpu utilization on all non global zones from Global Zone rajaniyer123 Solaris / OpenSolaris 3 10-09-2008 01:43 AM
c: define constants kpachopoulos Programming 5 08-19-2006 03:31 PM
LXer: Variables Won't Constants Aren't: LXer Syndicated Linux News 0 07-26-2006 04:33 PM
Global Values do not work in /etc/inputrc? Akhran Debian 1 09-14-2005 10:12 AM
CSS - Constants? dushkinup Programming 1 05-02-2004 01:08 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:25 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration