7 Replies - 528 Views - Last Post: 06 November 2011 - 06:55 PM Rate Topic: -----

#1 mahkoe  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 67
  • Joined: 12-March 11

Return value from pow() function is larger than long double

Posted 06 November 2011 - 05:24 PM

I was experimenting with various things in a small program when I noticed some odd behaviour. This is the line of code that puzzled me:
cout << pow(2,512) << endl;

After not receiving any error messages when I was expecting at least 20 lines of compiler gibberish, I was forced to ask myself, "what kind of 512 byte variable is pow() returning???" I tried to figure it out by looking at the definition in the library, but after 20 seconds of looking at cmath I wanted to gouge my eyes out. So I was wondering, how does pow() return such massive variables and how can I reproduce this in my own functions? Thanks a lot

Is This A Good Question/Topic? 1
  • +

Replies To: Return value from pow() function is larger than long double

#2 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1616
  • View blog
  • Posts: 5,707
  • Joined: 03-August 09

Re: Return value from pow() function is larger than long double

Posted 06 November 2011 - 05:58 PM

it returns a double which is only 8 bytes. doubles can represent VERY large values but loose accuracy at such values. here is a look at double precision floating point values. it shows that a double has 11 bits allocated for the exponent, that means that it can hold exponents up to 2048. this exponent is multiplied by a binary fraction(the other 52 bits) however at such high exponents even a small change to the binary fraction results in large changes to the actual value. changing the binary fraction by 0.0000000000000001 could change the value by 20 to 30(those numbers are just really rough guesses, not necessarily accurate).

This post has been edited by ishkabible: 06 November 2011 - 06:02 PM

Was This Post Helpful? 0
  • +
  • -

#3 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2013
  • View blog
  • Posts: 3,038
  • Joined: 21-June 11

Re: Return value from pow() function is larger than long double

Posted 06 November 2011 - 05:58 PM

pow returns a double, not an integer type. Doubles do not have 512 bits, but they can represent numbers of this size because they don't represent all numbers accurately - they "round off" the less significant bits.

For more information how doubles are stored you can see the wikipedia article on floating point numbers.
Was This Post Helpful? 1
  • +
  • -

#4 mahkoe  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 67
  • Joined: 12-March 11

Re: Return value from pow() function is larger than long double

Posted 06 November 2011 - 06:03 PM

I see. This actually explains a lot of other phenomenons I've been facing. Also, this should be in a different thread altogether, but do you know how I could assign some ridiculously large number, such as 987643234567890987645345678986543245678987543456789765434567876543567654 to a double without my compiler saying that it's too long for a double? thanks

This post has been edited by mahkoe: 06 November 2011 - 06:06 PM

Was This Post Helpful? 0
  • +
  • -

#5 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2013
  • View blog
  • Posts: 3,038
  • Joined: 21-June 11

Re: Return value from pow() function is larger than long double

Posted 06 November 2011 - 06:11 PM

It's not telling you that the number is too large for a double - it's telling you that it's too large for an int. 98...54 is an integer literal, not a double literal. Things like double x = 4; are valid because the integer 4 is implicitly convertible to double. double x = 98...54; is illegal because 98...54 is too large for an integer.

To make it work, you should write it as a double in the first place, which means adding ".0" to the end of the literal.
Was This Post Helpful? 0
  • +
  • -

#6 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1616
  • View blog
  • Posts: 5,707
  • Joined: 03-August 09

Re: Return value from pow() function is larger than long double

Posted 06 November 2011 - 06:11 PM

the compiler won't stop(well mine doesn't, let me check the standard) you from assigning any literal value even if the assignment makes no sense. it *should* however warn you if you have the correct command line arguments set.
int f(short x) {
	std::cout<<x<<'\n';
}

int main() {
	int x = 0xFFFFFFFFFFFFFFFFFFFFFFFFF;
	double y = 5E10000;
	double z = 4178147892437842318743743289812348901243;
	f(0xFFFFFFFFFFFFFFFFFFFFFFFFF);
	std::cout<<y<<'\n';
    return 0;
}

this gives me a bunch of warnings telling me my literals are too big.

This post has been edited by ishkabible: 06 November 2011 - 06:16 PM

Was This Post Helpful? 0
  • +
  • -

#7 mahkoe  Icon User is offline

  • D.I.C Head

Reputation: 1
  • View blog
  • Posts: 67
  • Joined: 12-March 11

Re: Return value from pow() function is larger than long double

Posted 06 November 2011 - 06:23 PM

Okay, thanks a lot for your time, this was a big help for me
Was This Post Helpful? 0
  • +
  • -

#8 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1616
  • View blog
  • Posts: 5,707
  • Joined: 03-August 09

Re: Return value from pow() function is larger than long double

Posted 06 November 2011 - 06:55 PM

ok after reading this draft of the C++03 standard i have some more answers. i couldn't find anything explicit on the subject of literals but i found conversion rules in section 4.7 that seem to cover it.

Quote

2 If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo
2n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation,
this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]

3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field
width); otherwise, the value is implementation-defined.


so per my understanding. if the destination is an unsigned value, the bit pattern of the value must be maintained. if the source value is signed then it is implementation defined. my compiler seems to maintain the bit pattern for signed values as well.

int main() {
	int x = 0xFFFFFFFFFFFFFFFFFFFFFFFFF; //implementation defined
	unsigned int a = 0xF0F0F0F0F0F0F0U; //same bit pattern
	std::cout<<0xF0F0F0F0U<<'\n'; //prints the same as below
	std::cout<<a<<'\n'; //same as above
	std::cout<<x<<'\n'; //implementation defined
    return 0;
}


i can't find where it says anything about literals that are too big to fit into any POD type. the lexical definitions don't place a cap on the size of literals though. it seems that the assumption is that the compiler won't do anything about it as no error is explicitly mentioned in the standard.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1